Google Chat
Proxy for the Google Chat v1 REST API. Unlike sheets/docs/slides/drive,
Chat is idp_passthrough only — its API doesn't support service-account
domain-wide-delegation user-impersonation, so there is no google_sa mode.
Every request carries the caller's own OAuth grant, and the policy layer
adds operator-controlled guards on which spaces an agent may touch.
Overview
Typical uses:
- An agent lists the spaces a user is in and summarizes recent messages
(
list_spaces,list_messages,get_message). - A notification bot posts and later edits/deletes its own message, or
reacts to one (
create_message,update_message,delete_message,create_reaction,delete_reaction). - A space-admin workflow provisions a space and manages membership
(
create_space,add_member,remove_member,delete_space).
Two notes specific to Chat:
chat:admintools have upstream prerequisites. Space and membership management require the calling user to be a space manager and a configured Google Chat app; these tools may legitimately return403PERMISSION_DENIED— a Chat-side authorization outcome, not a gateway fault. The dedicatedchat:adminscope lets an operator grant messaging (chat:write) without also granting space/member management.- The Google OAuth client must have the Chat API enabled and the Chat app configured for user-auth calls to succeed.
Default policy
The connector ships policy/chat.rego
(package pbac.connectors.identos.google_chat). It enforces:
1. IdP-routing subject obligation
subject_obligations contains obl if {
input.resource.type == "urn:connector:identos:google-chat"
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 Chat call succeeds.
2. blocked_space_ids deny (read + write)
A "nuclear" deny: the space is off-limits to this connector entirely, reads and writes both blocked. Use it to shield a sensitive space (leadership, HR) from LLM-driven workflows.
3. read_only_space_ids deny (write only)
Listed spaces allow GET but deny the mutating routes (messages, reactions,
and space/member management). Reads still work — useful for an agent that
should observe but not post in a space.
Supplying operator data
curl -X PUT http://localhost:8080/admin/policy/data/pbac/operator/connectors/identos.google-chat \
-H "X-Admin-API-Key: $PBAC_ADMIN_API_KEY" \
-d '{
"blocked_space_ids": ["spaces/AAAA_leadership"],
"read_only_space_ids": ["spaces/BBBB_announce"]
}'
Scope model
| Scope | Used for | |
|---|---|---|
| PBAC scopes (internal) | chat:read, chat:write, chat:admin | Route authorization — chat:admin gates space/member management separately from messaging, so you can grant an agent chat:write (post/edit/react) without space-create/delete or member changes |
| Upstream OAuth scopes | chat.spaces, chat.messages, chat.memberships | The Google-side grants the user must consent to. (delete_space additionally needs chat.delete, a restricted scope not requested by default.) |
See Google Workspace: multi-connector setup for how chat's scopes compose with drive, gmail, and calendar on a single Google IdP.
Manifest reference
- ID:
identos.google-chat - Version:
1.0.0 - Resource type:
urn:connector:identos:google-chat
Supported auth modes
| Type | Details |
|---|---|
idp_passthrough | requires IdP google |
Setup fields
| ID | Label | Default | Secret? | Notes |
|---|---|---|---|---|
base_url | API base URL | https://chat.googleapis.com | no | — |
Scopes
| Scope |
|---|
chat:read |
chat:write |
chat:admin |
Routes
| Method | Pattern | Scope | Resource template |
|---|---|---|---|
GET | /v1/spaces | chat:read | — |
GET | /v1/spaces/{space_id} | chat:read | chat://{{space_id}} |
GET | /v1/spaces/{space_id}/members | chat:read | chat://{{space_id}} |
GET | /v1/spaces/{space_id}/members/{member_id} | chat:read | chat://{{space_id}} |
GET | /v1/spaces/{space_id}/messages | chat:read | chat://{{space_id}} |
GET | /v1/spaces/{space_id}/messages/{message_id} | chat:read | chat://{{space_id}} |
GET | /v1/spaces:findDirectMessage | chat:read | — |
GET | /v1/spaces/{space_id}/messages/{message_id}/reactions | chat:read | chat://{{space_id}} |
POST | /v1/spaces/{space_id}/messages | chat:write | chat://{{space_id}} |
PATCH | /v1/spaces/{space_id}/messages/{message_id} | chat:write | chat://{{space_id}} |
DELETE | /v1/spaces/{space_id}/messages/{message_id} | chat:write | chat://{{space_id}} |
POST | /v1/spaces/{space_id}/messages/{message_id}/reactions | chat:write | chat://{{space_id}} |
DELETE | /v1/spaces/{space_id}/messages/{message_id}/reactions/{reaction_id} | chat:write | chat://{{space_id}} |
POST | /v1/spaces | chat:admin | — |
PATCH | /v1/spaces/{space_id} | chat:admin | chat://{{space_id}} |
DELETE | /v1/spaces/{space_id} | chat:admin | chat://{{space_id}} |
POST | /v1/spaces/{space_id}/members | chat:admin | chat://{{space_id}} |
DELETE | /v1/spaces/{space_id}/members/{member_id} | chat:admin | chat://{{space_id}} |
MCP tools
| Name | Scope | Description |
|---|---|---|
list_spaces | chat:read | List Chat spaces the authenticated user is a member of. |
get_space | chat:read | Get a single Chat space's metadata. |
list_members | chat:read | List memberships in a Chat space. |
get_member | chat:read | Get a single membership in a Chat space. |
list_messages | chat:read | List messages in a Chat space. |
get_message | chat:read | Get a single message by ID. |
find_direct_message | chat:read | Find the direct-message space with a specific user. Pass name=users/{user} as a query parameter. |
list_reactions | chat:read | List reactions on a message. |
create_message | chat:write | Post a message to a Chat space. Pass {"text": "..."} or a cards payload. Reversible via delete_message. |
update_message | chat:write | Update a message you authored. Pass updateMask (e.g. "text") as a query parameter and the new fields in the body. |
delete_message | chat:write | Delete a message you authored. |
create_reaction | chat:write | Add an emoji reaction to a message. Pass {"emoji": {"unicode": "👍"}}. |
delete_reaction | chat:write | Remove a reaction you added from a message. |
create_space | chat:admin | Create a named Chat space. Requires a configured Chat app / appropriate caller rights. Pass the Space body (displayName, spaceType). |
update_space | chat:admin | Update a Chat space. Pass updateMask (e.g. "displayName") as a query parameter and the new fields in the body. |
delete_space | chat:admin | Delete a Chat space. Irreversible — requires space-manager rights. |
add_member | chat:admin | Add a member to a Chat space. Pass the Membership body (member.name = users/{user}). |
remove_member | chat:admin | Remove a member from a Chat space. |
Operator data schema
Keys the operator can supply under data.pbac.operator.connectors["identos.google-chat"].* — consumed by the connector's policy.
| Key | Type | Description |
|---|---|---|
blocked_space_ids | array | Chat space IDs that are off-limits to this connector — reads and writes both denied. |
read_only_space_ids | array | Chat space IDs where writes (messages, reactions, space/member management) are denied regardless of the caller's scope. Reads still work. |