Skip to main content
Use the Gmail and Google Drive twins to test Google connection flows, token refresh, and identity checks against seeded accounts. The twins support authorization codes, S256 PKCE, and RS256-signed OpenID Connect ID tokens.

Provision and configure your connection

Provision the services your app uses:
Wait until the Twin Run is ready, then copy its returned environment variables into your app’s test environment. Use the provider-specific variables when both twins run together: Configure your OAuth client to use the returned authorization and token URLs. Configure its ID-token verifier to use the returned discovery, JWKS, or certificate URL. These variables are connection settings: map them to the configuration options your client library accepts.
The twin signs tokens with synthetic keys. Keep signature, audience, issuer, expiry, and nonce checks enabled, and use the twin’s public keys in your test environment. Google’s production public keys cannot verify a twin-issued token.

Register your callback

The default client ID is google-twin-client-id and its synthetic secret is google-twin-client-secret. The default registered callbacks are:
  • http://localhost:3000/oauth/callback
  • http://127.0.0.1:3000/oauth/callback
  • https://client.example.test/oauth/callback
To use another callback or client, save a Scenario with the following fields under seed_config. Replace the callback with your app’s exact URL, then provision the Twin Run from that Scenario.
Use only the service entries your Scenario needs. For a saved Scenario ID:
Callback matching is exact, including the scheme, hostname, port, path, and query string. Keep the client secret in your app’s server-side test configuration.

Complete the authorization flow

Start an authorization-code request at the returned *_AUTH_URL: The twin selects a seeded account and immediately redirects to your callback with a single-use code and the unchanged state. It does not open a real Google sign-in or consent screen. After validating state, exchange the code with a form-encoded POST to the returned *_TOKEN_URL. Send grant_type=authorization_code, client_id, client_secret, code, the same redirect_uri, and the matching code_verifier. Successful responses include access_token, token_type, expires_in, and the granted scope. An offline grant also includes refresh_token. A grant containing openid includes a signed id_token; API-only grants do not. Identity scopes do not grant mailbox or file access. For example, add https://www.googleapis.com/auth/gmail.readonly or https://www.googleapis.com/auth/drive.readonly for read-only provider access.

Verify the ID token in Python

Install the Google authentication library with its HTTP transport:
For direct twin URLs, use verify_token with the returned certificate endpoint. Set the audience explicitly, then check the issuer and the nonce saved when you started this login:
Pass the id_token from your code exchange and the nonce stored in your application’s login session. Use provider_prefix="GOOGLE_DRIVE" for Drive. The library verifies the signature, audience, and issue/expiry times; the explicit checks bind the token to the expected issuer and login. The default issuer is https://accounts.google.com. If your Scenario sets oidc_issuer, pass that exact value as expected_issuer, including any trailing slash. Use the verified sub claim as the account identifier. Call provider APIs with the access_token. Clients that accept OIDC metadata can use *_OIDC_DISCOVERY_URL and its advertised jwks_uri. When you use Arga’s deployment gateway, Google’s public certificate paths on www.googleapis.com also route to the twin keys. Direct local clients should use the returned verification URLs.

Refresh and identity behavior

Send a form-encoded POST to *_TOKEN_URL with grant_type=refresh_token, refresh_token, client_id, and client_secret. Refresh retains the original identity and granted scopes. An openid grant returns a new signed ID token with an access-token hash in at_hash. The initial ID token contains your authorization request’s nonce. Refreshed ID tokens omit it. The Python example verifies an initial login token; apply signature, audience, issuer, and time validation to refreshed tokens without requiring the original nonce to be present. Email claims require an email scope, and name claims require a profile scope. Hosted-domain membership is explicit:
  • Gmail uses the hd value seeded in its Scenario profile.
  • Drive emits hd only for a principal with account_type: "workspace". Accounts left at auto, including custom-domain consumers, omit it.
Check the verified hd claim when testing domain restrictions. An email address ending in your domain is not proof of Workspace membership. Authorization codes expire after 600 seconds and access/ID tokens after 3,600 seconds by default. Scenario fields authorization_code_ttl_seconds and access_token_ttl_seconds customize these lifetimes. Twins use the current clock unless you explicitly seed base_time. Gmail and Drive in the same Twin Run share signing keys. Different runs use separate keys. Keys persist through resets within a run; resetting clears access tokens, refresh grants, and authorization codes, while an already issued ID token remains cryptographically verifiable until expiry.

Troubleshoot a connection

See the Gmail and Google Drive references for provider API behavior.