Skip to main content
Version: Latest

Google Calendar

Proxy for the Google Calendar v3 REST API. Dual auth by design — the typical production setup runs two managed resources at once:

  • calendar-user in idp_passthrough mode for human users who want an agent to read their schedule, find free slots, or update their own events.
  • calendar-rooms in google_sa mode for a booking agent that schedules meetings into Workspace resource (room) calendars on everyone's behalf.

Overview

The policy layer recognises this split and lets the operator lock each mode down differently:

  • User-mode managed resources typically carry read_only_calendar_ids for calendars the user is on but shouldn't let an agent edit (shared team, executive).
  • Room-mode managed resources typically run with room_only_mode: true, which refuses any call whose calendar_id isn't a Workspace resource calendar (*@resource.calendar.google.com).

Default policy

The connector ships policy/calendar.rego (package pbac.connectors.identos.google_calendar). It enforces four things:

1. IdP-routing subject obligation

Same shape as drive/gmail — non-Google session + idp_passthrough mode triggers a require_authn_at obligation.

2. private_calendar_ids deny (read + write)

deny contains msg if {
input.resource.type == "urn:connector:identos:google-calendar"
input.resource.calendar_id
some private in data[...].private_calendar_ids
input.resource.calendar_id == private
...
}

A "nuclear" deny: the calendar is off-limits to this connector entirely, reads and writes both blocked. Use it when the service account has been shared a sensitive calendar (executive, HR, legal) for one-off reasons but you don't want it exposed to LLM-driven workflows.

3. read_only_calendar_ids deny (write only)

Listed calendars allow GET but deny POST/PATCH/PUT/DELETE. Reads still work — useful for agents that should surface but not modify certain shared calendars.

4. room_only_mode deny

deny contains msg if {
input.resource.type == "urn:connector:identos:google-calendar"
data[...].room_only_mode == true
input.resource.calendar_id
not endswith(input.resource.calendar_id, "@resource.calendar.google.com")
...
}

A booking-agent safety net. When enabled, every calendar_id must look like a Workspace resource calendar. If the agent (or, more importantly, a prompt-injected response it's acting on) tries to touch a human calendar, the request is denied. Makes the service account's broad Workspace grants safe to deploy.

Supplying operator data

curl -X PUT http://localhost:8080/admin/policy/data/pbac/operator/connectors/identos.google-calendar \
-H "X-Admin-API-Key: $PBAC_ADMIN_API_KEY" \
-d '{
"private_calendar_ids": ["ceo@example.com"],
"read_only_calendar_ids": ["team-alpha@example.com"],
"room_only_mode": true
}'

Scope model

ScopeUsed for
PBAC scopes (internal)calendar:read, calendar:events:write, calendar:adminRoute authorization
Upstream OAuth scopescalendar.readonly, calendar.eventsGoogle-side grants the user consents to (idp_passthrough mode); the service-account flow doesn't use these

See Google Workspace: multi-connector setup for how calendar's scopes compose with drive and gmail on one Google IdP.

Manifest reference

  • ID: identos.google-calendar
  • Version: 1.0.0
  • Resource type: urn:connector:identos:google-calendar

Supported auth modes

TypeDetails
idp_passthroughrequires IdP google
google_sasetup fields: sa_key_env, domain

Setup fields

IDLabelDefaultSecret?Notes
base_urlAPI base URLhttps://www.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 — useful for shared / room calendars where no human caller is involved.
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
calendar:read
calendar:events:write
calendar:admin

Routes

MethodPatternScopeResource template
GET/calendar/v3/users/me/calendarListcalendar:read
GET/calendar/v3/calendars/{calendar_id}calendar:readcalendar://{{calendar_id}}
GET/calendar/v3/calendars/{calendar_id}/eventscalendar:readcalendar://{{calendar_id}}
GET/calendar/v3/calendars/{calendar_id}/events/{event_id}calendar:readcalendar://{{calendar_id}}/event/{{event_id}}
POST/calendar/v3/calendars/{calendar_id}/eventscalendar:events:writecalendar://{{calendar_id}}
PATCH/calendar/v3/calendars/{calendar_id}/events/{event_id}calendar:events:writecalendar://{{calendar_id}}/event/{{event_id}}
DELETE/calendar/v3/calendars/{calendar_id}/events/{event_id}calendar:events:writecalendar://{{calendar_id}}/event/{{event_id}}
POST/calendar/v3/calendars/{calendar_id}/events/quickAddcalendar:events:writecalendar://{{calendar_id}}
POST/calendar/v3/freeBusycalendar:read
GET/calendar/v3/calendars/{calendar_id}/aclcalendar:admincalendar://{{calendar_id}}

MCP tools

NameScopeDescription
list_calendarscalendar:readList every calendar the authenticated user has on their calendar list (primary + shared + subscribed).
get_calendarcalendar:readGet a calendar's metadata (summary, timezone, description).
list_eventscalendar:readList events on a calendar. Supports time filters (timeMin/timeMax), single-event expansion, and free-text search.
get_eventcalendar:readGet a single event by ID.
create_eventcalendar:events:writeCreate a new event on a calendar. Provide either the Google Calendar event body (full schema) or the convenience fields summary/start/end/attendees.
update_eventcalendar:events:writeUpdate an event (partial). Only supplied fields are modified.
delete_eventcalendar:events:writeDelete an event. Recurring events: pass sendUpdates=all to notify attendees.
quick_add_eventcalendar:events:writeCreate an event from natural-language text (e.g. "Lunch with Alice Thursday 1pm"). Uses Calendar's quickAdd parser.
query_free_busycalendar:readQuery free/busy information for a set of calendars over a time window. Returns only busy intervals — no event details.
list_aclcalendar:adminList the access-control rules on a calendar (who it's shared with and how).

Operator data schema

Keys the operator can supply under data.pbac.operator.connectors["identos.google-calendar"].* — consumed by the connector's policy.

KeyTypeDescription
private_calendar_idsarrayCalendar IDs that are off-limits to this connector — reads and writes both denied. Useful for executive or HR-sensitive calendars that Workspace has shared to the service account but the operator wants shielded.
read_only_calendar_idsarrayCalendar IDs where writes (create/update/delete) are denied regardless of the caller's scope. Reads still work.
room_only_modebooleanWhen true, only calendars whose ID ends with @resource.calendar.google.com (Google Workspace resource/room calendars) are addressable. Useful for booking agents that should never touch human calendars.