Drive & Files

`gog <group> raw` — Sensitive Field Audit

gog <group> raw — Sensitive Field Audit

This document records the security audit performed before shipping the gog <group> raw <id> subcommands, which dump the canonical Google API response as JSON for programmatic / LLM consumption.

#Redaction rule

raw applies field-level redaction only when the user did not explicitly name a field via --fields. Rationale:

  • The default (implicit fields=* for Drive, or no mask for the other
  • APIs) pulls in capability URLs and third-party–stashed metadata that callers rarely want and can leak if piped into an LLM, shared in a bug report, or committed to a repo.

  • When a caller writes --fields "id,name,thumbnailLink", they named
  • thumbnailLink deliberately. Redacting a user-named field would be surprising and user-hostile.

Summary: redact what the user didn't ask for; honor what they did.

#Per-endpoint Findings: Workspace Content

#1. docs.Documents.Getgog docs raw

REST ref: https://developers.google.com/docs/api/reference/rest/v1/documents/get Go type: https://pkg.go.dev/google.golang.org/api/docs/v1#Document

FieldRiskDefault handling
inlineObjects.*.embeddedObject.imageProperties.contentUriShort-lived (~30 min) bearer-style authenticated image URLShip as-is
inlineObjects.*.embeddedObject.imageProperties.sourceUriMay reference private source URLsShip as-is

Why not redact: the Docs API has no field mask, so the principled "redact only what the user didn't name" rule has no escape hatch. These image URIs are short-lived (~30 min) and require the caller's auth anyway — substantially lower risk than Drive's thumbnailLink. The lossless guarantee is valued more than the marginal hardening.

No credentials, tokens, or OAuth metadata in the response.

#2. sheets.Spreadsheets.Getgog sheets raw

REST ref: https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/get Go type: https://pkg.go.dev/google.golang.org/api/sheets/v4#Spreadsheet

FieldRiskDefault handling
developerMetadataThird-party apps may stash arbitrary KV including secretsWarn on stderr if present, do not redact
sheets[].data.rowData.values[].userEnteredValue.formulaValue (only with --include-grid-data)Formulas can embed API keys via IMPORTRANGE, hardcoded tokens in cellsWarn on stderr when --include-grid-data is set, do not redact

--include-grid-data is off by default because grid payloads can be multi-MB and are the primary leakage vector.

No redaction applied to Sheets output; warnings only. Redacting cell content would defeat the purpose of a lossless dump.

#3. slides.Presentations.Getgog slides raw

REST ref: https://developers.google.com/slides/api/reference/rest/v1/presentations/get Go type: https://pkg.go.dev/google.golang.org/api/slides/v1#Presentation

FieldRiskDefault handling
slides[].pageElements[].image.contentUrlShort-lived authenticated image URL (same class as Docs contentUri)Ship as-is
slides[].pageElements[].image.sourceUrlPossibly private origin URLShip as-is
slides[].pageElements[].video.urlDrive video refs may carry signed accessShip as-is

Same rationale as Docs: no field mask, short-lived URLs, auth-gated, lower risk than Drive. Lossless guarantee preferred.

#4. drive.Files.Get with fields=*gog drive raw (highest risk)

REST ref: https://developers.google.com/drive/api/reference/rest/v3/files/get Go type: https://pkg.go.dev/google.golang.org/api/drive/v3#File

FieldRiskDefault handling
thumbnailLinkTime-limited signed URL that bypasses normal auth for ~hours. Classic leak vector.Redact
webContentLinkDirect download URL; capability URLRedact
exportLinksPer-MIME authenticated export URLsRedact
resourceKeyCapability token for link-shared files; effectively a shared secretRedact
appPropertiesArbitrary app-stashed KV; apps commonly misuse for secretsRedact
propertiesPublic custom properties, still frequently (mis)used for tokensRedact
contentHints.thumbnail.imageBase64 thumbnail bytes; large and unnecessaryRedact
permissions[].emailAddress, owners[].emailAddress, sharingUser, lastModifyingUser, trashingUserNon-collaborator emails (PII) when fields=* enumerates full ACLNot redacted — caller already has access to the file; enumeration is a conscious --fields choice

Reminder: all of the above are redacted only when --fields is not set. Passing --fields "id,name,thumbnailLink" returns thumbnailLink verbatim — the user named it.

#Per-endpoint Findings: Other Services

#5. gmail.Users.Messages.Getgog gmail raw

REST ref: https://developers.google.com/gmail/api/reference/rest/v1/users.messages/get Go type: https://pkg.go.dev/google.golang.org/api/gmail/v1#Message

The subcommand name "raw" collides with Gmail's native format=raw (base64url-encoded RFC822 blob). gog gmail raw defaults to format=FULL (full parsed Message struct) and exposes --format full|metadata|minimal|raw for users who want Gmail's RAW. Help text documents both senses.

FieldRiskDefault handling
payload.body.data (base64url)Email body; user already has read accessShip as-is
payload.headersMay contain Received-SPF, DKIM-Signature, routing metadataShip as-is
raw (when --format=raw)Full RFC822 source including original attachmentsShip as-is — user asked for it

No credential leakage risk. Caller already holds the Gmail scope.

#6. calendar.Events.Getgog calendar raw

REST ref: https://developers.google.com/calendar/api/v3/reference/events/get Go type: https://pkg.go.dev/google.golang.org/api/calendar/v3#Event

FieldRiskDefault handling
attendees[].emailAttendee emails (PII)Ship as-is — caller already on the event ACL
conferenceData.entryPoints[].uriMeeting URLs (Meet/Zoom) including passwords in paramsShip as-is — user asked for the event
extendedProperties.private / extendedProperties.sharedApp-stashed KV; third-party apps may use for secretsShip as-is (same rationale as Sheets developerMetadata)

No redaction. The risk surface here is fundamentally the same as simply reading the event in the Calendar UI.

#7. people.People.Getgog people raw / gog contacts raw

REST ref: https://developers.google.com/people/api/rest/v1/people/get Go type: https://pkg.go.dev/google.golang.org/api/people/v1#Person

Both gog people raw and gog contacts raw call the same underlying people.Get endpoint. Requires --person-fields (Google's field mask for the People API, required on every request).

FieldRiskDefault handling
emailAddresses, phoneNumbers, addresses, biographiesPII; user's own contactsShip as-is
userDefined[]Arbitrary KV custom fields; may store secretsShip as-is
metadata.sources[].profileMetadata.userTypesAccount type disclosureShip as-is

#8. tasks.Tasks.Getgog tasks raw

REST ref: https://developers.google.com/tasks/reference/rest/v1/tasks/get Go type: https://pkg.go.dev/google.golang.org/api/tasks/v1#Task

FieldRiskDefault handling
notesUser-entered free textShip as-is
links[].linkExternal URLs attached to a taskShip as-is

No sensitivity concerns beyond the caller's own task data.

#9. forms.Forms.Getgog forms raw

REST ref: https://developers.google.com/forms/api/reference/rest/v1/forms/get Go type: https://pkg.go.dev/google.golang.org/api/forms/v1#Form

FieldRiskDefault handling
items[].questionItem.question.gradingCorrect answers for graded formsShip as-is — caller is the form owner
linkedSheetIdID of the responses spreadsheetShip as-is

No redaction. The form owner already has access to everything here.

#Cross-cutting observations

  • Google APIs never return OAuth access tokens, refresh tokens, or client
  • secrets in resource responses. The risk is capability URLs and app-stashed custom metadata, not credential disclosure in the API contract itself.

  • gog drive raw is the most dangerous command; the others are modest in
  • comparison.

  • This audit covers all currently shipped raw subcommands.