{"record":{"id":"4f456022bc1ab731","repo":"google-gemini/gemini-cli","slug":"host-hostname-is-not-an-allowed-host-for-goog","errorCode":null,"errorMessage":"Host \"${hostname}\" is not an allowed host for Google Credential provider.","messagePattern":"Host \"(.+?)\" is not an allowed host for Google Credential provider\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/core/src/agents/auth-provider/google-credentials-provider.ts","lineNumber":62,"sourceCode":"    if (urlObj.protocol !== 'https:') {\n      throw new Error(\n        `Protocol \"${urlObj.protocol}\" is not secure. Google Credential provider requires HTTPS.`,\n      );\n    }\n\n    const hostname = urlObj.hostname;\n    const isRunAppHost = CLOUD_RUN_HOST_REGEX.test(hostname);\n\n    if (isRunAppHost) {\n      this.useIdToken = true;\n    }\n    this.audience = hostname;\n\n    if (\n      !this.useIdToken &&\n      !ALLOWED_HOSTS.some((pattern) => pattern.test(hostname))\n    ) {\n      throw new Error(\n        `Host \"${hostname}\" is not an allowed host for Google Credential provider.`,\n      );\n    }\n\n    // A2A spec requires scopes if configured, otherwise use default cloud-platform\n    const scopes =\n      this.config.scopes && this.config.scopes.length > 0\n        ? this.config.scopes\n        : ['https://www.googleapis.com/auth/cloud-platform'];\n\n    this.auth = new GoogleAuth({\n      scopes,\n    });\n  }\n\n  override async initialize(): Promise<void> {\n    // We can pre-fetch or validate if necessary here,\n    // but deferred fetching is usually better for auth tokens.","sourceCodeStart":44,"sourceCodeEnd":80,"githubUrl":"https://github.com/google-gemini/gemini-cli/blob/5024443c7217464a66e98f80d73172a26440bd8f/packages/core/src/agents/auth-provider/google-credentials-provider.ts#L44-L80","documentation":"After the HTTPS check, the provider only mints tokens for hosts on an allowlist: any *.googleapis.com host or a Cloud Run host (*.run.app). For other hosts it refuses, because ADC access tokens are scoped to Google APIs and sending them elsewhere would leak credentials uselessly. This is a deliberate security restriction, not a bug.","triggerScenarios":"targetUrl host is a third-party domain or on-prem service; a custom hostname that is not under googleapis.com or run.app; using google-credentials for a non-Google A2A server; the hostname has a trailing dot or port that changes the regex match.","commonSituations":"Pointing google-credentials at a partner's A2A server; an internal gateway CNAME that resolves to Cloud Run but whose hostname is not *.run.app; testing against localhost (which also fails the host check, not just HTTPS).","solutions":["Use google-credentials only for Google API or Cloud Run endpoints.","For non-Google hosts, switch to oauth2, http (Bearer), or apiKey auth.","If the service is fronted by Cloud Run, use the *.run.app URL directly so the allowlist matches.","Extend ALLOWED_HOSTS only if you control the target and understand token-scope implications."],"exampleFix":"# before - third-party host rejected\nauth:\n  type: google-credentials\nagent_card_url: https://partner.example/.well-known/agent-card.json\n\n# after - use a Bearer token auth for non-Google hosts\nauth:\n  type: http\n  scheme: Bearer\n  token: $PARTNER_TOKEN","handlingStrategy":"validation","validationCode":"const ALLOWED = [/^.+\\.googleapis\\.com$/, /^(.*\\.)?run\\.app$/];\nfunction isAllowedGoogleHost(url: string): boolean {\n  const host = new URL(url).hostname;\n  return ALLOWED.some((re) => re.test(host));\n}\nif (!isAllowedGoogleHost(targetUrl)) {\n  throw new Error('google-credentials only targets googleapis.com or run.app.');\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Reserve google-credentials for Google API / Cloud Run targets.","Use the *.run.app URL directly when fronting Cloud Run via a custom domain.","Switch non-Google targets to oauth2/http/apiKey."],"tags":["auth","google-credentials","security","allowlist"],"backgroundTag":null,"analyzedSha":"5024443c7217464a66e98f80d73172a26440bd8f","analyzedAt":"2026-08-12T06:01:53.711Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}