[Bug]: Antigravity BYO OAuth client can never pass the live probe — cloudcode-pa.googleapis.com cannot be enabled on an operator's own project · Issue #566 · duolahypercho/codex-router · GitHub
Skip to content

[Bug]: Antigravity BYO OAuth client can never pass the live probe — cloudcode-pa.googleapis.com cannot be enabled on an operator's own project #566

Closed

Description

@lengocanh2005it

What happened?

On 44029b8 (v0.5.1), the operator-owned ("BYO") Antigravity OAuth client that
README now requires cannot complete the live probe, because
cloudcode-pa.googleapis.com is a private Google API that a normal Cloud
project is not allowed to enable
. The provider is unreachable for anyone
without an allowlisted project, and README does not mention this prerequisite.

Sign-in itself works. The probe fails:

$ providers login antigravity-oauth
Google Antigravity OAuth sign-in completed with the operator-owned OAuth client.
The route remains disabled until an explicit live compatibility test succeeds.

$ providers probe antigravity-oauth --live --yes
Antigravity project bootstrap failed (HTTP 403; HTTP 403).

The credential record is written correctly (version: 3, managed_by: codex-router, client pair + refresh token present), so this is not the
"incompatible older record" path.

Calling v1internal:loadCodeAssist directly with the same access token shows
what the two 403s are:

{
  "error": {
    "code": 403,
    "status": "PERMISSION_DENIED",
    "message": "Cloud Code Private API has not been used in project <PROJECT_NUMBER> before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/cloudcode-pa.googleapis.com/overview?project=<PROJECT_NUMBER> then retry.",
    "details": [{ "reason": "SERVICE_DISABLED", "metadata": { "service": "cloudcode-pa.googleapis.com" } }]
  }
}

loadCodeAssist is billed to the project that owns the calling OAuth client.
With the bundled vendor client (0.5.1) that was Google's own allowlisted
project; with a BYO Desktop client it is the operator's project, which does not
have the private API enabled — and cannot enable it:

$ gcloud services enable cloudcode-pa.googleapis.com --project=<PROJECT_ID>
ERROR: (gcloud.services.enable) PERMISSION_DENIED: Permission denied to enable
service [cloudcode-pa.googleapis.com]
- '@type': type.googleapis.com/google.rpc.ErrorInfo
  domain: serviceusage.googleapis.com
  metadata:
    permission: servicemanagement.services.bind
    service: servicemanagement.googleapis.com
  reason: AUTH_PERMISSION_DENIED

servicemanagement.services.bind is a producer-side permission: only
allowlisted consumer projects may bind cloudcode-pa. This was run by the
project owner, through gcloud's own first-party client, so no IAM role the
operator can grant themselves changes the outcome. The Cloud Console route is
also a dead end — cloudcode-pa has no API Library entry, so
/apis/api/cloudcode-pa.googleapis.com/overview?project=… redirects to
/apis/library/… and fails to load.

What I expected

Either:

  1. README/INSTALL to state the prerequisite plainly — Antigravity OAuth needs a
    Google Cloud project that is allowlisted for cloudcode-pa.googleapis.com,
    with instructions on how an operator obtains that (Gemini Code Assist
    licence? Antigravity onboarding? something else?) — and the probe to surface
    SERVICE_DISABLED as that specific, actionable message instead of
    bootstrap failed (HTTP 403; HTTP 403); or
  2. a documented supported path for operators whose project cannot be
    allowlisted.

Right now the documented flow (create a Desktop client you own → login → probe →
enable) terminates in an unactionable 403 for what I suspect is every user
without a pre-allowlisted project.

Suggested small fix regardless of the answer

loadAntigravityProject() in src/antigravity-project.mjs collapses every
attempt into HTTP <status> strings, so the response body — which contains
Google's exact reason and the activation URL — is discarded. Surfacing
error.status / error.details[].reason (at least for 403 SERVICE_DISABLED)
would have turned an hour of guessing into one line.

Which app do you route through?

Codex

Platform

Windows

Version

44029b8 (package version 0.5.1), Node 22.23.2, Windows 11.

Reproduced with a fresh Google OAuth Desktop app client created per README
§Antigravity, consent screen in Testing with the account added as a test user
(the Google consent step itself succeeds — Signed in).

Activity

  1. duolahypercho commented on Sep 2, 2026

    @duolahypercho
    Owner

    This is a thorough piece of work — running gcloud services enable as the project owner and showing servicemanagement.services.bind as a producer-side permission is what makes it conclusive. That rules out every operator-side remedy, which is the part that would otherwise have been guessed at.

    Confirming the mechanism: loadCodeAssist bills the project that owns the calling OAuth client. The bundled vendor client billed Google's allowlisted project; the operator-owned client the README now requires bills yours. So the BYO change moved the call onto a project that cannot be allowlisted, and sign-in succeeding while the probe fails is exactly the expected shape of that.

    #572 addresses your option 1, both halves:

    • The probe now says what happened. It was discarding the response body and reporting HTTP 403; HTTP 403 while Google was returning PERMISSION_DENIED / SERVICE_DISABLED with the service name. It now reports that the OAuth client's project is not allowlisted for cloudcode-pa.googleapis.com, that this is a private API an ordinary project cannot enable, and that sign-in succeeded — so nobody else re-runs a login that was never broken.
    • README states the prerequisite, including plainly that without an allowlisted project this provider cannot currently be used.

    One deliberate omission: the message quotes only Google's structured fields, not its free-text message, because that text embeds your project number and a console URL built from it, and this string is printed and logged. There is a test asserting neither leaks.

    I am leaving this issue open, because #572 makes the failure legible without making the provider work — and nothing in this repository can, since the allowlist is Google's. Your option 2 is the open question: whether there is any supported path for an operator whose project cannot be allowlisted, or whether Antigravity should be documented as requiring an allowlisted project and left at that. That is a maintainer call about the provider's future, not something to settle in an error-message patch.

    If you have a Gemini Code Assist licence or an Antigravity onboarding that did allowlist a project, knowing which of those does it would turn the README note into real instructions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions