Shared drive folders accumulate exports, old reports, and one-off uploads that nobody ever
circles back to clean up. Google Drive has lifecycle rules for individual files only through
manual trash, with no scheduled, folder-wide retention sweep of its own. This blueprint reads
what is actually under a folder, flags what has outlived its retention window, and reports
the reclaimable size, not just a guess.
This blueprint was created by Mohit Jeswani.
How it works
list_stale_files (io.kestra.plugin.googleworkspace.drive.List) runs a Drive v3 search
query scoped to folder_id, server-side filtered to trashed = false and createdTime
older than retention_days. Read-only; nothing in Drive is changed. allowFailure: true
covers an API or auth error without failing the flow outright.
evaluate (io.kestra.plugin.core.output.OutputValues) counts the matched files and sums
their size in bytes with a jq filter.
route (io.kestra.plugin.core.flow.If):
- compliant: logs that nothing is stale.
- alert: posts the count and reclaimable bytes to Slack.
summary logs the count, size, and severity, closing the governance cycle.
errors alerts Slack if the flow itself fails, for example invalid service account
credentials.
What you get
- A number, not a guess: the exact count and byte total of what is sitting past retention
under a folder.
- A filter computed server-side by Drive's own query language, so the date comparison does
not depend on paging through every file client-side first.
- A read-only check with zero risk of deleting a real file.
Who it's for
- Platform and IT teams who own shared Drive folders and have no process catching exports or
reports nobody cleaned up.
- Teams evaluating the Google Workspace plugin who want a worked example of
drive.List
used with a Drive v3 query for a governance check, distinct from this repo's existing
Google Workspace blueprints, none of which read Drive file metadata this way.
Why orchestrate this with Kestra
Drive answers one query at a time through its own UI; it does not keep a schedule, compare
file age against a retention policy you declare, or notify anyone. Kestra keeps
retention_days as a flow input, turns the query into a Slack page with a real byte count,
and keeps a full execution history of every run.
Prerequisites
- A Google Cloud service account with Drive API access and read permission on the target
folder (shared with the service account's email, or domain-wide delegation configured for
the Workspace).
- A Drive folder with at least one file old enough to confirm the filter logic against.
- A Slack incoming webhook URL.
This flow calls the Google Drive API directly over HTTPS; there is no official local Google
Drive emulator, so list_stale_files cannot be exercised against a local Docker container.
Secrets
GOOGLE_SERVICE_ACCOUNT_JSON: the full service account JSON key used by
list_stale_files. In Kestra OSS, provide it as the base64-encoded environment variable
SECRET_GOOGLE_SERVICE_ACCOUNT_JSON.
SLACK_WEBHOOK_URL: used by alert and the errors block. In Kestra OSS, provide it as
the base64-encoded environment variable SECRET_SLACK_WEBHOOK_URL.
Inputs
| Input |
Default |
Purpose |
folder_id |
<your-drive-folder-id> |
Drive folder to scan |
retention_days |
180 |
Age past which a file is reported stale |
max_stale_count |
1 |
Matched-file count that triggers the Slack alert |
Outputs
{{ outputs.list_stale_files.files }}: every matched file (id, name, size, version,
mimeType, createdTime, parents, trashed).
{{ outputs.evaluate.values.stale_count }} / .stale_size_bytes: how many files are stale
and their combined size.
{{ outputs.evaluate.values.severity }}: OK, STALE_FILES_FOUND, or CRITICAL.
Pitfalls
folder_id scopes the query to direct children of that folder only; Drive's in parents
operator is not recursive, a nested subfolder's files are not included.
size is null for native Google Docs/Sheets/Slides (they have no byte size of their own);
the jq sum treats a null size as 0, so a folder full of native Google files can report
a correct file count with a reclaimable size of 0.
createdTime, not the last-modified time, is what this check compares against
retention_days; a file edited yesterday but created a year ago still counts as stale.
Quick start
- Add the
GOOGLE_SERVICE_ACCOUNT_JSON and SLACK_WEBHOOK_URL secrets.
- Share the target folder with the service account's email address.
- Set
folder_id to that folder and run the flow, confirming summary logs a count.
- Lower
retention_days below a known file's age to confirm alert fires with its size.
- Enable the
weekly trigger once retention_days matches your actual retention policy.
How to extend
- Loop over several
folder_id values with io.kestra.plugin.core.flow.Loop to cover more
than one shared folder in a single scheduled run.
- Add a remediation branch that moves matched files to a separate "pending deletion" Drive
folder instead of deleting them outright, gated behind the
auto_remediate/dry_run pair
used elsewhere in this repo's guard blueprints.
- Group the alert by
mimeType to see whether the reclaimable space is mostly large binary
exports or native Google files with zero size.
Links