Google Drive
Proxy for the Google Drive v3 REST API. Ships with a tenant-filled deny template — the connector author knows the shape of Drive, the operator fills in the specifics (which folders are blocked, which tags are sensitive).
Overview
Drive is the first dual-auth connector. Pick:
idp_passthroughwhen the caller is a real human and the agent should act as them — reads and writes apply to the user's own Drive, respecting every share / membership the user already has. Requires the operator to register Google as an IdP on the AS.google_sawhen the caller is an unattended service (CI job, automation agent) and the operator owns the data. Uses a Google service account with domain-wide delegation impersonating whichever Workspace user was stamped into the managed-resource setup.
A single managed resource binds to one auth mode. To serve both
shapes of caller, create two managed resources (e.g. drive-user and
drive-sa). The policy can key off input.resource.name to apply
different obligations.
Default policy
The connector ships policy/drive.rego
(package pbac.connectors.identos.google_drive). It enforces three
things:
1. IdP-routing subject obligation
subject_obligations contains obl if {
input.resource.type == "urn:connector:identos:google-drive"
input.connector.upstream_auth.type == "idp_passthrough"
input.subject.idp_provider != "google"
obl := { "type": "require_authn_at", "idp": "google", ... }
}
When the caller's session is from a non-Google IdP but the connector is
set up in idp_passthrough mode, the PDP emits a require_authn_at
obligation. The client (Claude Code, a custom agent, the admin UI) is
expected to redirect the user to log in at Google. No access is granted
until they do.
2. blocked_folders deny
deny contains msg if {
input.resource.type == "urn:connector:identos:google-drive"
input.action.method in {"GET", "PATCH", "DELETE"}
some folder_id in data["pbac.operator.connectors.identos.google-drive"].blocked_folders
input.resource.parent_folder_id == folder_id
msg := sprintf("drive: access to folder %v is blocked by operator", [folder_id])
}
Operators supply a list of folder IDs under
data.pbac.operator.connectors["identos.google-drive"].blocked_folders.
Any GET/PATCH/DELETE against a file whose parent_folder_id
matches is denied with a human-readable message.
3. sensitive_tags deny
deny contains msg if {
input.resource.type == "urn:connector:identos:google-drive"
input.action.method in {"PATCH", "DELETE"}
some tag in input.resource.tags
tag in data["pbac.operator.connectors.identos.google-drive"].sensitive_tags
...
}
Files carrying custom-property labels the operator has flagged sensitive
(e.g. HR, BOARD, LEGAL) are read-only: PATCH/DELETE is denied,
but reads are still allowed.
Both data keys sit in the operator-owned policy-data namespace
(pbac.operator.connectors.<id>.*), so they survive connector upgrade
and uninstall — the operator's classification decisions aren't tied to
the connector package lifecycle.
Supplying operator data
curl -X PUT http://localhost:8080/admin/policy/data/pbac/operator/connectors/identos.google-drive \
-H "X-Admin-API-Key: $PBAC_ADMIN_API_KEY" \
-d '{
"blocked_folders": ["0AABBCC..."],
"sensitive_tags": ["HR", "BOARD", "LEGAL"]
}'
The gateway adapter is responsible for populating
input.resource.parent_folder_id and input.resource.tags on every
request. Without those fields the deny rules have nothing to match on —
verify with an OPA trace in Grafana if a deny doesn't fire.
Scope model
Two vocabularies are at play:
| Scope | Used for | |
|---|---|---|
| PBAC scopes (internal) | drive:files:read, drive:files:write, drive:admin | Route authorization inside PBAC — the PDP decides which MCP tools the caller can invoke |
| Upstream OAuth scopes | https://www.googleapis.com/auth/drive.readonly, https://www.googleapis.com/auth/drive.file | What the IdP (Google) must grant in the user's access token for idp_passthrough to work |
When this connector is provisioned in idp_passthrough mode, the gateway
automatically merges its declared upstream scopes into the Google IdP's
scopes list. Users who authenticated before the connector was
installed will see "stored IdP token missing required scopes" until they
re-log at Google.
See Google Workspace: multi-connector setup for how this works across drive + gmail + calendar sharing a single Google IdP.
Manifest reference
- ID:
identos.google-drive - Version:
1.0.0 - Resource type:
urn:connector:identos:google-drive
Supported auth modes
| Type | Details |
|---|---|
idp_passthrough | requires IdP google |
google_sa | setup fields: sa_key_env, domain |
Setup fields
| ID | Label | Default | Secret? | Notes |
|---|---|---|---|---|
base_url | API base URL | https://www.googleapis.com | no | — |
upstream_auth.type | Authentication | idp_passthrough | no | idp_passthrough forwards each user's own Google OAuth token (recommended). google_sa uses a Workspace service account with domain-wide delegation impersonating a fixed user. |
sa_key_env | Service account key | — | yes | Pick a secret containing the service-account JSON. Required only for the google_sa auth mode. / shown when upstream_auth.type == 'google_sa' |
domain | Workspace domain | — | no | placeholder: example.com / Required only for the google_sa auth mode. / shown when upstream_auth.type == 'google_sa' |
Scopes
| Scope |
|---|
drive:files:read |
drive:files:write |
drive:admin |
Routes
| Method | Pattern | Scope | Resource template |
|---|---|---|---|
GET | /drive/v3/files | drive:files:read | — |
GET | /drive/v3/files/{file_id} | drive:files:read | drive://{{file_id}} |
GET | /drive/v3/files/{file_id}/permissions | drive:admin | drive://{{file_id}} |
POST | /upload/drive/v3/files | drive:files:write | — |
PATCH | /drive/v3/files/{file_id} | drive:files:write | drive://{{file_id}} |
DELETE | /drive/v3/files/{file_id} | drive:admin | drive://{{file_id}} |
MCP tools
| Name | Scope | Description |
|---|---|---|
list_files | drive:files:read | List files in Google Drive. Supports standard Drive query syntax for filtering (e.g. "name contains 'report'" or "mimeType = 'application/pdf'"). |
get_file | drive:files:read | Get metadata for a single Drive file by its file ID. |
list_file_permissions | drive:admin | List the sharing permissions on a Drive file. |
create_file_metadata | drive:files:write | Create a Drive file's metadata record (no binary content). Use this to register placeholders, folders, or shortcuts. For binary uploads, use the Drive web UI or a dedicated upload client. |
update_file_metadata | drive:files:write | Update a Drive file's metadata (name, description, starred flag, etc.). |
delete_file | drive:admin | Permanently delete a Drive file. Irreversible — prefer trashing via update_file_metadata when possible. |
Operator data schema
Keys the operator can supply under data.pbac.operator.connectors["identos.google-drive"].* — consumed by the connector's policy.
| Key | Type | Description |
|---|---|---|
blocked_folders | array | Drive folder IDs the operator wants made read-only (blocks GET/PATCH/DELETE of files whose parent_folder_id matches). |
sensitive_tags | array | Custom-property tag names (e.g. HR, BOARD) to treat as read-only: writes and deletes are denied when any of these tags appear on the file. |