Google Drive (headless, no per-user login)
Google Drive (headless, no per-user login)
Captain can index Google Drive without every user clicking “Allow.” Instead of per-user OAuth, your Google Workspace admin authorizes a single service account once. Captain then reads Drive as a specific user you name on each request — a single file, one folder (recursively), or that user’s entire Drive.
This is the pattern to use when you want to index Drive content at scale, on a schedule, or on behalf of many users, without a login step in the loop.
How it works
- You create a service account in Google Cloud and download its JSON key.
- Your Workspace super admin authorizes that service account for read-only Drive access, domain-wide (a one-time grant in the Admin console).
- On each indexing request you send the service-account key plus a
subject_email— the Workspace user whose Drive Captain should read. Captain mints a short-lived token as that user and reads only what that user can see.
Nothing durable is stored on Captain’s side beyond the request; the token is minted per job and discarded.
One-time setup
Every step below is done by someone with Google Workspace super administrator rights on your domain. It takes about 15 minutes and is done once — after that, indexing is a plain API call.
Step 1 — Create a service account and key
You need a Google Cloud project to hold the service account. If your organization doesn’t use Google Cloud, that’s fine — any Google account can create a project for free, and this use case requires no billing.
- Go to console.cloud.google.com.
- Create a project (or pick an existing one). Top bar → project picker →
New Project → name it e.g.
captain-drive-indexing→ Create. - Enable the Drive API: APIs & Services → Enable APIs and services → search “Google Drive API” → Enable.
- Create the service account: IAM & Admin → Service Accounts → Create
service account. Give it a name (e.g.
captain-indexing) → Create and continue → skip the optional roles → Done. (No project roles are needed — this account’s access comes entirely from the Workspace delegation grant in Step 2.) - Create a key: open the service account → Keys tab → Add key →
Create new key → JSON → Create. A
.jsonfile downloads. This is theservice_account_jsonyou’ll send to Captain — keep it secret. - Note the service account’s numeric Client ID (also called the “Unique ID” or “OAuth2 Client ID”). You’ll need it in Step 2. Find it on the service account’s Details tab, or under IAM & Admin → Service Accounts (the “OAuth 2 Client ID” column).
Google does not offer a way to create a service account entirely inside the Admin console — the account itself must be created in Google Cloud, as above. Only the delegation grant (Step 2) lives in the Admin console.
Step 2 — Authorize the service account (domain-wide delegation)
This is the grant that lets Captain read Drive as your users. It’s done in
the Admin console (admin.google.com), which is a different console from
the Cloud one in Step 1.
- Go to admin.google.com → Security → Access and data control → API controls.
- In the Domain-wide delegation panel, click Manage Domain-Wide Delegation.
- Click Add new and enter:
- Client ID — the numeric Client ID from Step 1 (not the service account’s email address).
- OAuth scopes — exactly:
- Click Authorize.
Grant only drive.readonly. Captain never writes to or deletes from Drive.
Scoping to read-only keeps the grant safe and speeds any internal security
review.
The grant can take a few minutes to propagate (occasionally up to ~30). If
your first indexing call returns unauthorized_client, wait and retry.
Choosing which user to index (subject_email)
Captain reads Drive as the subject_email you pass, so pick the user
whose content you want:
- A specific person’s Drive → their email (e.g.
analyst@yourco.com). - A Shared Drive / team content → any user who is a member of that Shared Drive. Files that user can’t see are simply skipped.
- An org-wide “service” identity → many teams create a dedicated
Workspace user (e.g.
indexing@yourco.com), share the relevant Drives and folders with it, and always impersonate that one account. This keeps the indexed scope explicit and easy to audit.
Indexing
All three endpoints take the same auth fields — the service-account key and the user to impersonate — and differ only in scope.
A single file
file_id is the /d/<id>/ segment of a Drive file URL.
A folder (recursively)
folder_id is the trailing segment of a folder URL
(drive.google.com/drive/folders/<folder_id>). Subfolders are indexed too.
An entire Drive
Every response is { "job_id": "...", "status": "pending" }. Poll
GET /v2/collections/{name}/jobs/{job_id} for progress, then query the
collection with POST /v2/collections/{name}/query.
Passing the key JSON. service_account_json is the entire contents of
the .json key file, as a single JSON string. In most languages,
read the file and JSON-encode its text before putting it in the request body.
What gets indexed
- Regular files (PDF, DOCX, XLSX, CSV, TXT, images, etc.) — downloaded and processed normally.
- Native Google Docs, Sheets, and Slides — exported automatically before indexing: Docs and Slides → PDF, Sheets → XLSX. You don’t do anything; the exported file is what gets indexed.
- Shared Drives — included, as long as
subject_emailis a member. - Skipped: Google Forms and Sites (no exportable document body), and any
file the
subject_emailuser can’t access (logged and skipped — the job continues).
Troubleshooting
Security notes
- The grant is read-only (
drive.readonly) — Captain can never modify or delete Drive content. - Captain reads only what the impersonated
subject_emailcan see. To limit scope, impersonate a dedicated user and share only the intended Drives with it. - The service-account JSON key is a credential — treat it like a password. You can revoke it any time in Google Cloud (delete the key), or revoke all access by removing the delegation grant in the Admin console.
- Every read is attributable to the
subject_emailin your Google audit logs.