Use your own GitHub or Google OAuth client
Configure an app-owned OAuth client for user integrations, register callbacks, and plan scopes and credential changes.
Use your app's OAuth client when users connect Google or GitHub integrations, instead of the platform's shared client. You configure one OAuth provider per provider type on your app. This changes who issues new user grants; it does not install a shared bot or connect an account by itself.
Before you begin
You need developer access to the target app in the developer portal, access to the provider's developer console, and your platform API host. The hosted platform uses https://platform.archastro.ai; use your deployment's platform host if different, not your frontend or docs host.
For the API alternative below, you also need a developer bearer token with app-level scope for the target app. An ordinary runtime user token is not sufficient. Keep OAuth client secrets on the server, never in a browser bundle or mobile app.
1. Create the provider client
-
Open the Google Cloud console and select the project that will own your app's OAuth credentials.
-
Enable the APIs your integration uses: Gmail API, Google Calendar API, and Google Drive API for the default Google connection options.
-
In Google Auth Platform, configure Branding, Audience, and Data Access. Supply your app name, support contact, authorized domains, and the scopes described below. While testing an external app, add your test users under Audience.
-
Under Clients, create an OAuth client with application type Web application. This is the server client, even if you also have an iOS app.
-
Add both Authorized redirect URIs, replacing the origin only if you use a different platform deployment:
https://platform.archastro.ai/connect/google/callback https://platform.archastro.ai/auth/federated/google/callbackThe first handles integration connections; the second handles Google federated sign-in. These are platform callbacks, not your app's post-login return URL.
-
Save the web client ID and client secret for the next step.
GitHub
- In GitHub, open Settings → Developer settings → OAuth Apps → New OAuth App for the intended owner. Set your app's name and homepage.
- Set Authorization callback URL to
https://platform.archastro.ai/connect/github/callback, using your platform deployment's origin if different. - Save the client ID and generate a client secret. If you also use GitHub federated sign-in, register
https://platform.archastro.ai/auth/federated/github/callbackwith the client used for that flow. GitHub OAuth Apps support one callback URL; use a GitHub App OAuth client if you need multiple callback URLs on the same client. - For a GitHub App OAuth client, register the relevant callback URLs in the GitHub App settings and configure the user permissions your integration needs. This guide configures user OAuth, not a shared GitHub App installation.
2. Enable the client for user integrations
In the portal
- Select your app in the developer portal and open its OAuth page.
- Add or edit the Google or GitHub provider. Enter the client ID and secret from step 1.
- Set Callback URLs to the allowed return URLs on your application, for example
https://app.example.com/oauth/complete. These allow the app's federatedredirect_uriorigin; they are separate from the platform callbacks registered at Google or GitHub. Only allow origins you control. - Set Scopes for federated sign-in if needed. Google's login defaults are
email,profile, andopenid; they do not grant Gmail access. The integration connection flow requests its own service scopes, described in step 3. - Turn on Use for user integrations and save. Its API field is
mint_user_integrations; the default isfalse. The provider must also be enabled.
This flag supports Google and GitHub only. It is independent of auto_create_integration, which creates or reconnects an integration after federated sign-in and currently supports GitHub only. Enabling Google minting does not automatically create a Google integration when someone signs in.
Through the API
Send this JSON body to POST /protected/api/v1/developer/apps/<app_id>/oauth_providers on your platform host, with Authorization: Bearer <developer_token> and Content-Type: application/json. Replace the example values with your Google web client credentials and your app's return URL:
{
"provider": "google",
"client": "YOUR_WEB_CLIENT_ID",
"client_secret": "YOUR_WEB_CLIENT_SECRET",
"callback_urls": "https://app.example.com/oauth/complete",
"scopes": "email,profile,openid",
"mint_user_integrations": true
}
The request field is client, not client_id. The response exposes client_id, the provider resource id, and mint_user_integrations, but not the secret. A successful POST returns HTTP 201. POST can update the existing provider of that type; do not treat it as a way to bypass client-change rules.
For an existing provider, send PATCH /protected/api/v1/developer/apps/<app_id>/oauth_providers/<oauth_provider_id> with:
{
"mint_user_integrations": true,
"enabled": true
}
PATCH leaves omitted fields unchanged. Use client and client_secret when updating credentials. For GitHub, use "provider": "github" when creating the provider and supply its credentials; omit the Google-specific scopes example to use GitHub's login defaults, read:user and user:email.
3. Configure Google scopes and verification
Add the scopes your connection will request to Google Auth Platform's Data Access configuration. The built-in Google connector requests these identity scopes for both connection options:
https://www.googleapis.com/auth/userinfo.emailhttps://www.googleapis.com/auth/userinfo.profile
Its service scopes depend on the option the user selects:
| Service | Read Only | Full Access |
|---|---|---|
| Gmail | https://www.googleapis.com/auth/gmail.readonly |
https://www.googleapis.com/auth/gmail.readonly and https://www.googleapis.com/auth/gmail.send |
| Calendar | https://www.googleapis.com/auth/calendar.readonly |
https://www.googleapis.com/auth/calendar |
| Drive | https://www.googleapis.com/auth/drive.readonly |
https://www.googleapis.com/auth/drive |
The default options include Gmail, Calendar, and Drive. Do not configure only the login scopes and expect the connector to work. Request only the services and access your app actually needs when building a custom connection flow.
Your Google Cloud project owns consent-screen publication and verification for these grants. Gmail read access is a restricted scope; an external production app generally needs Google's restricted-scope verification, and server-side storage or transmission of restricted data can require a security assessment. Check Google's scope classifications and verification requirements. Internal apps and other exceptions have different requirements. Platform verification does not transfer to your client.
While an external app remains in Testing, access is limited to test users and refresh tokens for these service scopes normally expire after seven days. Plan publication and verification before relying on unattended connections.
No Google push setup is required: the platform does not wire Gmail watch notifications or Calendar channels into this integration. Gmail email ingestion polls hourly. Do not create Pub/Sub topics or notification webhooks for this guide.
4. Configure a mobile Google client, if applicable
For a native iOS app, create a separate iOS OAuth client in the same Google Cloud project for your bundle ID. Configure the Google Sign-In SDK with your own iOS client ID (GIDClientID in the bundled app) and its reversed-client-ID URL scheme. Never ship the web client secret in the app.
The SDK's serverClientID must be the web client ID from step 1, not the iOS client ID. A server authorization code is issued for that web client and must be exchanged using the same client on the platform.
Current native-connector limitation: the platform's Google connector state exposes server_client_id, but currently resolves it from platform-wide Google configuration, not the app's OAuth provider. The bundled iOS connector reads that value into GIDConfiguration(clientID:serverClientID:). Turning on mint_user_integrations alone does not change this discovery value. Do not assume the bundled native flow is ready for an app-owned web client: check that the returned server_client_id matches your web client before using it. If it does not, use the browser connection flow below; app-specific native discovery requires a platform change.
5. Connect a user and check the result
- Save the enabled provider with Use for user integrations on before starting a new user connection.
- Open a Google connection in the target app's user portal. From your backend, send
POST /protected/api/v1/developer/apps/<app_id>/users/<user_id>/portal/sessionsto your platform host with your app-scoped developer bearer token and JSON body{"redirect_path":"/connect/google"}. Use an existing user ID in that app. Redirect the user's browser to the response'surlimmediately: it authenticates that user, is single-use, and expires after 600 seconds. Treat the URL and response token as secrets. The app's App URL must point to its real user portal, not a placeholder or unrelated frontend. In the portal, select the services and access level, then start authorization. For agent installations, follow the personal OAuth workflow to create, authorize, and activate the installation in the target app. - Before approving consent, inspect the Google authorization URL. Its
client_idmust be your web client ID, and itsredirect_urimust be your platform's/connect/google/callbackURL. The flow requests fresh consent for the app-owned Google client. - Sign in as an allowed Google test user or a user eligible for your published app, approve the requested scopes, and finish the return to your app.
- Confirm the integration shows connected and the installation, if used, is active. Exercise the Gmail or other service operation you need. For GitHub, repeat with its connection UI and
/connect/github/callback.
If the authorization URL still names the shared platform client, check the app context, provider type, enabled, and mint_user_integrations. If Google reports a redirect mismatch, compare the complete URI, including scheme, host, path, and trailing slash, against the Google web client's authorized redirect URIs. If the client changed during authorization, restart the flow rather than replaying the old callback.
Change clients without breaking existing connections
- Existing connections keep their minting client. Turning the flag on does not migrate grants issued to the shared platform client. App-owned grants retain their provider association for token refresh. Turning the flag off does not move those grants back to the shared client.
- Changing the stored
client_idor disabling a Google or GitHub provider is rejected while integrations reference it. Have those users disconnect first, update the provider, then have them connect again. This applies through PATCH and POST upsert, even whenmint_user_integrationsis off. - Secret rotation for the same client ID is allowed. Update the stored secret while the old secret is still valid, verify connections, then retire the old secret at the provider.
- Deletion also requires disconnecting referenced integrations first. A GitHub App using OAuth during installation additionally pins compatible client and provider settings until that linkage is removed.
- In-flight callbacks cannot silently switch clients. If the provider identity or client ID changes between authorization and callback, the connection is rejected before token exchange. Start a new authorization after the change.
Continue with Installations to attach and verify the connection for an agent, or return to Integrations to choose between personal OAuth and shared app access.
Have feedback?
Help us make this page even more useful.
Tell us what you'd like to see expanded, which examples would help, or what workflow you want covered next. Every message gets read.