Read this first
Google Drive delivery works, but two current limitations decide how you must configure it.What Drive delivery is, and is not
Tornado authenticates to Drive as a Google service account using a signed JWT, the same credential type as Google Cloud Storage. There is no OAuth consent screen and no “sign in with Google” redirect. You create the service account, you share a folder with it, you paste its JSON key. The backend requests exactly one scope:drive.file under non-sensitive scopes and marks it Recommended. It grants
the ability to “Create new Drive files, or modify existing files, that you open with an app
or that the user shares with an app while using the Google Picker API or the app’s file
picker”. Tornado requests this narrower scope instead of unrestricted Drive access;
effective access also depends on the service account, app authorization and sharing settings.
Use a dedicated destination folder or Shared Drive. The OAuth scope is not a
replacement for reviewing the service account’s actual sharing permissions.
Tornado lists accessible files when resolving names and deletes accessible
delivered files; this guide does not promise that all pre-existing files are
invisible under every Google authorization configuration.
The step everyone misses: share the folder with the service account
A service account is a Google identity with its own email address. It is not you, it cannot see your Drive, and it is not a member of your organisation unless you add it. Sharing the destination folder with that email address is not optional. Skip it and you land in one of two failure modes:- You set a
folder_idthe service account cannot see. Drive does not distinguish “not shared with you” from “does not exist”, so every upload fails with a 404 on a folder that is plainly sitting in your browser. - You left
folder_idempty, so Tornado targets the service account’s own root Drive. That Drive belongs to a robot identity with no web UI you can log into, and it has no storage quota, so uploads fail withstorageQuotaExceededagainst a destination you cannot inspect.
Finding the service account’s email address
It is theclient_email field inside the JSON key file you downloaded. It always ends in
.iam.gserviceaccount.com:
Minimum and recommended access
Drive has no policy document. What you grant is one OAuth scope plus one sharing level, and Tornado picks the scope for you, so the only decision you make is the sharing level.Minimum
Those cover everything Tornado calls:
files.create (the resumable upload and its chunks),
files.list (finding a delivered file by name, and the one-item validation call), and
files.delete.
Recommended
The minimum sharing level is the recommendation. Content manager is already the lowest role that works, and Manager adds only member management and the ability to delete the shared drive itself, neither of which Tornado touches. One thing about placement is worth a line:Storage quota: use a Shared Drive, not My Drive
This is the single most important decision on this page, and the answer differs between My Drive and Shared Drives. Google’s Drive API documentation states it plainly:Service accounts don’t have storage quota and can’t own any files. Instead, they must upload files and folders into shared drives, or use OAuth 2.0 to upload items on behalf of a human user.Combine that with the ordinary Drive storage rule, “Only the files you own count toward your Google storage”, and the consequence follows:
Google Workspace caps uploads at 750 GB per day per user across My Drive and all shared
drives. High-volume delivery can hit this. Nothing on the Tornado side raises it.
Setup
1. Create a Google Cloud project and enable the Drive API
1
Create the project
Go to console.cloud.google.com/projectcreate,
or in the Cloud console open Menu > IAM & Admin > Create a Project.Enter a project name, optionally edit the project ID (it cannot be changed later), pick
a location, then click Create.An existing project is fine. The project only carries the service account and the API
enablement, it has nothing to do with where the files land.
2
Enable the Drive API
In the Cloud console go to Menu > APIs & Services > Library > Google Workspace,
click Google Drive API, then click Enable.Direct link: console.cloud.google.com/apis/library/drive.googleapis.comOr with the CLI:Skipping this step produces a 403 with
accessNotConfigured on the first upload, not
at configuration time.2. Create a service account and download its JSON key
1
Create the service account
Go to console.cloud.google.com/iam-admin/serviceaccounts,
select your project, click Create service account, enter a name such as
tornado-drive, then click Done.Assign no IAM roles. Cloud IAM roles do not grant Drive access. Drive permissions come
exclusively from Drive sharing, which is step 3.2
Create a JSON key
Click the service account’s email address, open the Keys tab, then
Add key > Create new key, select JSON, and click Create. The file
downloads automatically.Google notes that “This file is the only copy of this key. After you download the key
file, you cannot download it again.”
3
Note the client_email
3. Share the destination folder with the service account
- My Drive folder
4. Find the folder ID
Open the folder in Drive and read it out of the address bar. The ID is everything after/folders/:
/drive/folders/ is the shared
drive’s own ID, which is a valid parents value.
5. Configure Tornado
Storage is resolved per API key. A configuration set on one key does not apply to your other keys. Run this for every key you send jobs with.Field reference
Characters rejected in
folder_prefix:
Through the dashboard
The dashboard’s Drive tile is blocked by limitation 1 above, so this is recorded for completeness rather than as a working path. The wire format nests the config under the provider key:service_account_json and Destination folder ID to folder_id.
service_account_json is capped at 10,000 characters on this route. A standard Google key
file is roughly 2.3 KB, so this only bites if you paste something other than the key.
What “verified” actually proves
POST /user/gdrive validates the credentials live before saving, and the dashboard button
says Connect & verify. Be precise about what that check covers.
The validation mints an OAuth token from the JSON key, then issues a one-item
files.list. That proves the service account exists, the private key parses and signs,
the Drive API is enabled on the project, and the drive.file scope is granted.
It does not touch folder_id. The list call carries no folder filter, and under
drive.file a fresh service account has created nothing, so it returns an empty list and
the check passes.
Nothing is written. The dashboard’s S3 probe was extended to write, read back, open and
abort a multipart upload, and delete; Drive validation is a single read-only files.list
and was not changed. If you have read the AWS S3 page, do not carry over
what it says about the probe.
Troubleshooting
The job says Completed but nothing appears in my folder
Work through these in order.
1
Check which API key sent the job
The direct Drive configuration is per key. A key without it can inherit an
organization destination of another provider, or use legacy/managed storage
when no modern destination applies. Check the actual key and destination;
configure Drive with the
x-api-key you send these jobs with.2
Check that folder_id was not empty
An empty or omitted
folder_id sends everything to the service account’s own root
Drive, which no human can browse. There is no read-back endpoint for Drive
configuration, so if you are unsure, simply re-run POST /user/gdrive with the correct
folder_id. It overwrites the previous config for that key.3
Check the file name, not the folder tree
Drive does not create nested folders. If you set
base_folder or folder_prefix, look
for a flat file literally named videos/my-video.mp4 inside the destination folder,
not for a videos subfolder.4
Check that you are looking at the right Drive
A shared drive and a My Drive folder can have the same name. Confirm the ID in the URL
matches the
folder_id you configured.Permission and lookup errors
Quota errors
Download link problems
Thes3_url returned for a Drive delivery is a
https://drive.google.com/file/d/{id}/view link with no Tornado URL-expiry parameter,
and anyone opening it needs Drive permission on that file. Sharing the link with someone
outside the folder’s access list will show them a request-access page.
Tornado resolves that link by looking the file up by name inside the folder. Two jobs
that produce identical file names will collide, and the lookup returns whichever one Drive
answers with first. The generic backend delete also has a name-lookup path; job-file
deletion for multi-clip results uses recorded, validated file IDs and a deletion journal.
The ordinary single-file DELETE /jobs/{id}/file path currently uses S3 storage;
do not rely on it to delete a Drive object. Remove such an object in Drive.
Avoid duplicate names rather than relying on lookup order. Set a distinct
per-job folder value on POST /jobs, which is folded into the file name and keeps the
names unique.
Removing the configuration
DELETE.
Related
Custom Storage
S3, Azure Blob, GCS and Alibaba OSS configuration
POST /user/gdrive
Full endpoint reference