Skip to main content
Version: Latest

Google Docs

Proxy for the Google Docs v1 REST API — which is the entire API surface: create_document, get_document, and batch_update. Dual auth by design, like drive and calendar:

  • idp_passthrough mode for human users who want an agent to read or edit documents they own. Each request carries the caller's own OAuth grant.
  • google_sa mode (Workspace service account with domain-wide delegation) for headless workflows that read or write shared documents on a fixed identity's behalf.

Overview

Typical uses:

  • An agent reads a doc's structured content and summarizes it (get_document).
  • A drafting workflow creates a doc and inserts/templates text into it (create_document, then batch_update with insertText / replaceAllText).

Two upstream-shape notes specific to Docs:

  • No list endpoint. The Docs API can't enumerate documents; discover document IDs via the Google Drive connector (filter on mimeType = 'application/vnd.google-apps.document'), then operate on the ID here.
  • Everything mutating is batch_update. All content edits and deletes (insertText, replaceAllText, deleteContentRange, table ops) are request objects on batch_update; deleting an entire document file is the Drive connector's job.

Default policy

The connector ships policy/docs.rego (package pbac.connectors.identos.google_docs). It enforces:

1. IdP-routing subject obligation

subject_obligations contains obl if {
input.resource.type == "urn:connector:identos:google-docs"
input.connector.upstream_auth.type == "idp_passthrough"
input.subject.idp_provider != "google"
obl := { "type": "require_authn_at", "idp": "google", ... }
}

Same pattern as google-drive/gmail — a caller from a non-Google session gets a step-up obligation before any passthrough Docs call succeeds.

2. Blocked and read-only documents

Blocking a specific document is operator config on the general file-access control, not a rule in this connector. An identity source matches a document by its own id: ids in blocked are denied on reads and writes, ids in write_blocked are denied on writes only (batch_update), so reads still work. See File access control below for the shape — an identity source pools with any label or location source governing the same connector.

File access control

Documents can be gated by Drive Labels and/or by folder/shared-drive location — a document is returnable via get_document if it matches any governing source's approval (an approved label or an approved folder), and denied if it matches any source's blocked (pooled OR, deny-wins). This is configured through the shared file_access operator control, used across all Google file connectors (Docs, Sheets, Slides, Drive). Full mechanics (the pooled predicate, OR-combine and deny-wins, fail-closed rules) live in the File Access Control guide; for getting label/folder IDs and the required OAuth scopes, see the Google file access setup guide.

Configuration uses a two-level model:

  1. Define a policy per source — under pbac.operator.controls.file_access.sources, each source declares a type (label, location, or identity — the resource's own id), a required allowlist (any-of; file must match ≥1), a blocked denylist (file withheld if it matches any — always wins), and an optional write_blocked denylist that applies to mutating calls only. Approving a whole folder is a location source with the folder ID in required (Google Drive does not allow labels on folders):
curl -X PUT http://localhost:8080/admin/policy/data/pbac/operator/controls/file_access \
-H "X-Admin-API-Key: $PBAC_ADMIN_API_KEY" \
-d '{
"sources": {
"google-drive-labels": {
"type": "label",
"required": ["approved-for-ai"],
"blocked": ["restricted"]
}
},
"governed": {
"urn:connector:identos:google-docs": ["google-drive-labels"]
}
}'
  1. Activate per connector — under governed, list (as an array) which sources govern each connector's resource type; all listed sources pool into one OR-of-approvals, deny-wins decision — a file is returnable if it matches any source's required and withheld if it matches any source's blocked. Omitting a connector leaves it ungoverned (inert; no check). Once a source is configured and a connector is governed by it, enforcement is fail-closed: reads that cannot verify the file's values are denied (403).

The control resolves document IDs from tool invocations to fetch labels/location; file and scope requirements are documented in the spec at docs/superpowers/specs/2026-08-11-general-file-access-control-design.md.

Scope model

ScopeUsed for
PBAC scopes (internal)docs:read, docs:writeRoute authorization
Upstream OAuth scopesdocumentsGoogle-side grant the user consents to (idp_passthrough mode); the service-account flow uses the same scope on the SA

See Google Workspace: multi-connector setup for how docs' scopes compose with drive, gmail, and calendar on a single Google IdP.

Manifest reference

  • ID: identos.google-docs
  • Version: 1.1.0
  • Resource type: urn:connector:identos:google-docs

Supported auth modes

TypeDetails
idp_passthroughrequires IdP google
google_sasetup fields: sa_key_env, domain

Setup fields

IDLabelDefaultSecret?Notes
base_urlAPI base URLhttps://docs.googleapis.comno
upstream_auth.typeAuthenticationidp_passthroughnoidp_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_envService account keyyesPick a secret containing the service-account JSON. Required only for the google_sa auth mode. / shown when upstream_auth.type == 'google_sa'
domainWorkspace domainnoplaceholder: example.com / Required only for the google_sa auth mode. / shown when upstream_auth.type == 'google_sa'

Scopes

Scope
docs:read
docs:write

Routes

MethodPatternScopeResource template
POST/v1/documentsdocs:write
GET/v1/documents/{document_id}docs:readdocs://{{document_id}}
POST/v1/documents/{document_id}:batchUpdatedocs:writedocs://{{document_id}}

MCP tools

NameScopeDescription
create_documentdocs:writeCreate a new, empty document. Pass {"title": "..."}. Add content afterward with batch_update.
get_documentdocs:readGet a document's full structured content (body, styles, lists, etc.).
batch_updatedocs:writeApply one or more content edits (insertText, replaceAllText, deleteContentRange, table ops, styling, …) via Docs Request objects. This is also how you DELETE content.