Why You Need an OAuth App Before Anything Else
Every Google Drive to Salesforce integration starts in the same place, and it is not Salesforce. Before you can push a file into Drive, generate a Google Doc from an Opportunity, or sync folder contents onto a record, Google needs to know exactly who is calling its APIs and what they are allowed to touch. That is what an OAuth app is: your integration's registered identity inside Google Cloud, with a Client ID (public identifier) and a Client Secret (the password Salesforce uses to prove it is really you).
This walkthrough is the zoomed-in version of step 1 in our Google Drive technical guide (cloudsheer.com/integrations/google-drive/technical-guide): register the app, grant the minimum OAuth scopes, and whitelist the Salesforce callback URL. We will do all three in the Google Cloud console, then wire the result into Salesforce with an Auth Provider and Named Credential so no secret ever lives in code.
What You Need Before You Start
Five minutes of preparation saves an hour of backtracking. Have these ready:
- A Google account that can create projects in Google Cloud. For a company integration this should be a Google Workspace account, ideally one owned by IT rather than a personal login, because whoever creates the project controls the credentials.
- Access to the Google Cloud console at console.cloud.google.com. If your organization restricts project creation, ask your Workspace admin for the Project Creator role or have them create the project and grant you Editor on it.
- A Salesforce org with My Domain enabled (every modern org has this). You will need it for the callback URL.
- A one-line answer to: what will the integration actually do with Drive? Create files, read existing folders, generate Docs, or all three? The answer decides which scopes you request, and requesting less means fewer security reviews.
Step 1: Create the Google Cloud Project
Everything in Google's API world hangs off a project: the enabled APIs, the consent screen, the credentials, the quotas, and the audit logs. Create a dedicated one so the Salesforce integration is isolated from anything else your company runs on Google Cloud.
- Go to console.cloud.google.com and sign in.
- Click the project picker in the top bar (it shows your current project name, or 'Select a project'), then click New Project in the dialog's top right.
- Name it something you will recognize in a year, like salesforce-drive-integration. Do not reuse a sandbox or experiment project.
- If you are on Google Workspace, set Location to your organization so the project inherits company policies and does not live in 'No organization'.
- Note the auto-generated Project ID under the name field. You can edit it now, but never again after creation. The ID appears in audit logs and API errors, so a readable one helps.
- Click Create, wait a few seconds, then make sure the new project is selected in the picker before you touch anything else. Enabling APIs on the wrong project is the most common wasted half hour in this whole process.
Step 2: Enable the Google Drive and Google Docs APIs
A fresh project has zero APIs enabled. If you skip this step, every callout from Salesforce will come back with a 403 accessNotConfigured error that looks like a permissions problem but is not.
- In the left navigation, open APIs & Services, then Library.
- Search for Google Drive API, open it, and click Enable. This covers file upload, download, folder listing, sharing, and metadata.
- If your integration will create or edit Google Docs (for example, generating a proposal document from an Opportunity), search for Google Docs API and enable it too. Same for Google Sheets API if you write spreadsheets.
- Each API you enable gets its own quota page under APIs & Services, then Quotas. The Drive API default of 12,000 queries per minute per project is far more than a typical Salesforce integration needs, but know where the dial is.
Step 3: Configure the OAuth Consent Screen
The consent screen is what a user sees the first time Salesforce asks Google for access on their behalf: the app name, the publisher, and the list of permissions being requested. Google will not let you create OAuth credentials until this exists.
- Go to APIs & Services, then OAuth consent screen (in newer consoles this lives under Google Auth Platform; same settings, different label).
- Choose the User Type. Internal is the right answer for almost every company integration: only users in your Google Workspace can authorize, and Google never requires app verification. External is for when the authorizing account is outside your Workspace, and it puts you on the verification treadmill for sensitive scopes.
- App name: use something your users will trust when they see the consent prompt, like Acme Salesforce Integration. Avoid the word Google in the name; Google rejects it during verification.
- User support email: a team inbox, not a personal one.
- Authorized domains: add your company domain (for example acme.com). This must match the domain of any links you put on the consent screen.
- Developer contact information: again, a team inbox. Google emails this address about policy or verification issues.
- Skip the logo for now if you chose External. Uploading a logo forces a verification review even for otherwise unverified apps.
Step 4: Grant the Minimum OAuth Scopes
Scopes are the exact permissions your app requests, and this is the decision that determines whether your integration sails through or gets stuck in Google's verification process. Google sorts Drive scopes into tiers, and the tier you pick matters more than any other choice on this page.
- https://www.googleapis.com/auth/drive.file is the one to start with. It grants access only to files and folders your app created or that a user explicitly opened with it. It is non-sensitive, needs no verification, and covers the most common Salesforce pattern: the integration creates the files, so it can see the files.
- https://www.googleapis.com/auth/drive.readonly (read everything) and https://www.googleapis.com/auth/drive (full read-write on the entire Drive) are restricted scopes. On an External app these trigger Google verification and, for Drive specifically, an annual third-party security assessment (CASA) that costs real time and money. On an Internal app they work without verification, but least privilege still applies.
- https://www.googleapis.com/auth/documents if you enabled the Docs API and will create or edit documents.
- openid, email, and profile round out the set so Salesforce can identify which Google account authorized.
- In the Scopes step of the consent screen wizard, click Add or Remove Scopes, tick the ones above (filter by Drive API and Docs API), and save.
The rule we apply on every client build: start with drive.file, and only widen to a restricted scope when a concrete requirement demands reading files the integration did not create. Half the Drive integrations we ship never need more than drive.file plus documents.
Step 5: Add Test Users and Know the 7-Day Trap (External Apps Only)
If you chose External, your app starts in Testing status. Two things about Testing mode bite people:
- Only listed test users can authorize. Add the email address of your Salesforce integration user (and anyone else who will click Connect) under Test users on the consent screen page. Anyone else gets an access_denied error that looks like a scope problem but is not.
- Refresh tokens issued in Testing mode expire after 7 days. Your integration will work perfectly in the demo and then silently stop the following week, forcing a re-authorization. This is the single most confusing failure mode in Google OAuth. Once your scopes are final, click Publish App to move to In Production, which removes the 7-day expiry. If you only use non-sensitive scopes like drive.file, publishing does not require verification, just a confirmation click.
- Internal apps skip all of this. There is no test user list and no 7-day expiry, which is one more reason to prefer Internal for company integrations.
Step 6: Create the OAuth Client ID and Client Secret
Now the actual credentials Salesforce will hold.
- Go to APIs & Services, then Credentials, click Create Credentials, and choose OAuth client ID.
- Application type: Web application. Salesforce's authorization-code flow is a server-side web flow; do not pick Desktop or Service account here.
- Name it after where it will live, like Salesforce Named Credential - Production, so a future admin can tell your org's client apart from the sandbox one at a glance. Create one client per Salesforce environment.
- Authorized redirect URIs: you need the Salesforce callback URL here, and Salesforce only generates it after you create the Auth Provider in the next step. Add a placeholder like https://login.salesforce.com/services/authcallback/GoogleDrive for now; you will come back and replace it with the exact value.
- Click Create. A dialog shows your Client ID (ends in .apps.googleusercontent.com) and Client Secret. Copy both into a password manager immediately. You can re-view them later on the client's detail page, but treat the secret like a production password from this second onward: no email, no Slack, no spreadsheet.
Step 7: Whitelist the Salesforce Callback URL
The redirect URI is OAuth's anti-phishing lock: Google will only ever send the authorization code to a URL on your whitelist, character for character. Here is the round trip that gets the real value in place:
- In Salesforce Setup, search for Auth. Providers and click New. Provider Type: Google works out of the box; choose Open ID Connect instead if you want explicit control of the endpoints.
- Paste the Client ID into Consumer Key and the Client Secret into Consumer Secret.
- Default Scopes: openid email profile https://www.googleapis.com/auth/drive.file (space separated, plus documents if you scoped it).
- If you chose Open ID Connect: Authorize Endpoint URL is https://accounts.google.com/o/oauth2/v2/auth?access_type=offline&prompt=consent, Token Endpoint URL is https://oauth2.googleapis.com/token, and User Info Endpoint URL is https://openidconnect.googleapis.com/v1/userinfo. The access_type=offline and prompt=consent parameters are what make Google return a refresh token; without them your connection dies as soon as the first access token expires (about one hour).
- Save. Salesforce now displays a Callback URL at the bottom of the Auth Provider page, in the form https://your-domain.my.salesforce.com/services/authcallback/YourAuthProviderName.
- Copy that exact URL, go back to Google Cloud Credentials, edit your OAuth client, replace the placeholder in Authorized redirect URIs with it, and save. Exact means exact: https, the full My Domain host, the same suffix, no trailing slash.
Step 8: Wire It to a Named Credential and Test
With the handshake registered on both sides, put the credentials where Salesforce callouts can actually use them - and where no developer can read them back out.
- Create an External Credential (Setup, Named Credentials, External Credentials tab): Authentication Protocol OAuth 2.0, Authentication Flow Type Browser Flow, Identity Provider = the Auth Provider you just created, and the same scopes.
- Add a Principal on the External Credential (Named Principal if the whole org shares one Google identity, Per-User if each user connects their own Drive), then grant access to it via a permission set assigned to your integration user.
- Create a Named Credential pointing at https://www.googleapis.com with the External Credential attached and Generate Authorization Header enabled.
- Authenticate: on the Principal, click Authenticate (or have the integration user do it). You will see your consent screen with your app name and the drive.file permission, then land back in Salesforce with the status showing Configured.
- Smoke test with one Apex callout: an HttpRequest to callout:Your_Named_Credential/drive/v3/about?fields=user should return the connected account's email as JSON. If it does, OAuth is done and every later step of the build rides on this connection.
Common Errors and How to Fix Them
- redirect_uri_mismatch: the redirect URI Salesforce sent does not exactly match the whitelist. Compare character by character; the usual culprits are http vs https, a sandbox My Domain vs production, or a stale placeholder still saved in the Google client.
- Error 403: access_denied or 'app has not completed verification': your External app is in Testing and the authorizing user is not on the test user list, or you requested a restricted scope without verification. Add the test user, or drop to drive.file.
- invalid_scope: a typo in the scopes field. Scopes are full URLs and space separated; a stray comma breaks the whole string.
- No refresh token, connection dies after an hour: access_type=offline and prompt=consent are missing from the authorize URL. Fix the Auth Provider, then re-authenticate; Google only issues refresh tokens on a fresh consent.
- Error 403: accessNotConfigured: the Drive (or Docs) API is not enabled on the project the credentials belong to. Check the project picker; this is almost always the wrong-project mistake from Step 1.
- admin_policy_enforced: your Workspace admin has restricted third-party API access. They need to allowlist your Client ID under Security, then API Controls, then App Access Control in admin.google.com.
- Everything stops working exactly one week after setup: the app is still in Testing status and the refresh token hit the 7-day expiry. Publish the app to production status.
Security Checklist Before You Ship
- Scopes are the minimum the integration needs today, not what it might need someday. Widening later is a config change; a leaked over-scoped token is an incident.
- The Client Secret exists in exactly two places: the Google Cloud credentials page and the Salesforce Auth Provider. Never in Apex, custom settings, custom metadata, or a sandbox refresh.
- One OAuth client per Salesforce environment, so revoking sandbox credentials never touches production.
- Limit who holds Owner or Editor on the Google Cloud project; that role can read the secret and change the redirect whitelist.
- Rotate the Client Secret on staff departure or any suspected exposure: create a second secret on the same client, update the Auth Provider, then delete the old one for zero-downtime rotation.
- If you evaluate a service account with domain-wide delegation instead of user OAuth (common for org-wide document generation), treat it as the powerful thing it is: it can impersonate any user in the domain, so scope it tightly and guard its key like a master credential.
Where This Fits in the Full Google Drive Build
What you just built is step 1 of the production integration. The full technical guide at cloudsheer.com/integrations/google-drive/technical-guide continues from here: the data model and external IDs, inbound ingestion, outbound sync from Salesforce to Drive, surfacing files on records, field mapping, rate limits, monitoring, and the pitfalls we design out. Every code sample in that guide assumes the Named Credential you just finished.
If you build with AI agents, the same playbook ships as a free Claude Code skill: download it from the technical guide page or install it with npx skills add shivamgoel-cloudsheer/Claude-skills --skill google-drive-salesforce.
How Cloudsheer Can Help
We have shipped Google Drive and Google Docs integrations with Salesforce across client projects ranging from auto-generated proposal documents to full folder sync on Account records, and the OAuth setup above is where every one of them started. If you would rather have a senior architect do this end to end, or review the scopes and security model you already have, that is a 30-minute conversation.
Book a free discovery call at cal.com/cloudsheer-consulting/30min and we will map your Drive use case to the exact build it needs.
