Google Calendar Integration¶
The Google Calendar integration connects WhiteLotusAI's conversational interface to Google Calendar through the chat plugin and integrations service. It provides event retrieval and contains implementation paths for event creation and deletion.
This document describes the implementation identified in the available source snapshot. It does not certify production availability, end-to-end correctness, or enforcement of the intended read-only security policy.
Read-only enforcement is not yet established
The inspected implementation declares both event-creation and event-deletion operations. It also requests the calendar.events OAuth scope, which grants capabilities beyond read-only calendar access.
Do not treat this integration as strictly read-only until enforcement has been verified across tool dispatch, service routes, OAuth permissions, and alternate entry points.
At a glance¶
-
Event retrieval
Lists upcoming events from the user's primary calendar, with optional time-range filters.
-
OAuth authentication
Uses Google OAuth, PKCE, stored provider credentials, and application-level user identification.
-
Service integration
Routes requests from the chat plugin through the integrations service to Google Calendar API v3.
-
Verification required
Read-only enforcement, token-refresh reliability, timezone behavior, and complete runtime coverage remain open.
Documentation status
Source-inspected baseline. The findings below describe code paths and declarations identified in the source. They are not proof that the corresponding operations have passed integration tests or are enabled in a deployed environment.
1. Architecture¶
The integration has three primary implementation layers.
| Layer | Source location | Responsibility |
|---|---|---|
| Chat plugin | chat/package/app/plugins/google_cal/plugin.py |
Detects calendar-related requests, declares tools, and calls the integrations service. |
| Integration handlers | integrations/package/app/handlers/integration_handlers.py |
Handles OAuth, resolves user credentials, and exposes calendar endpoints. |
| Google Calendar client | integrations/package/app/managers/google_cal_client.py |
Contains Google Calendar API client operations. |
The integrations service registers its integration router under /api/integrations-svc. The chat plugin uses INTEGRATIONS_SERVICE_URL to construct the integration API base URL.
The effective external URL depends on gateway routing, environment configuration, and deployment.
Request flow¶
flowchart TD
U["User request"] --> C["WhiteLotusAI chat"]
C --> P["Google Calendar plugin"]
P --> R["Formatted response"]
P --> I["Integrations service"]
O["Google OAuth and PKCE"] -.-> A
I --> A["User identity and token resolution"]
A --> G["Google Calendar API v3"]
G --> I
I --> P
A -.-> T["Stored provider tokens"]
classDef action fill:#E8F1FE,stroke:#356AC3,color:#172B4D,stroke-width:1.5px
classDef security fill:#EDE9FE,stroke:#7C3AED,color:#3B0764,stroke-width:1.5px
classDef external fill:#DDF5E5,stroke:#25804B,color:#16452B,stroke-width:1.5px
classDef data fill:#FFF2CC,stroke:#B8860B,color:#4D3B00,stroke-width:1.5px
classDef response fill:#D1FAE5,stroke:#047857,color:#064E3B,stroke-width:1.5px
class U,C,P,I action
class O security
class A,G external
class T data
class R response
The diagram represents the documented logical flow. Exact runtime call ordering, network boundaries, and credential-storage behavior should be confirmed against the deployed configuration.
2. Tool definitions and supported operations¶
The inspected chat plugin declares three tools.
| Tool | Category | Purpose | Confirmation declared |
|---|---|---|---|
list_events |
READ |
Retrieves upcoming calendar events. | No |
create_event |
WRITE |
Creates a calendar event. | Yes |
delete_event |
WRITE |
Deletes an event by identifier. | Yes |
Tool metadata is not a security boundary
A tool's READ or WRITE category and its confirmation declaration describe plugin metadata. They do not, by themselves, demonstrate that every invocation path enforces the same policy.
For a strict read-only release, write operations must be rejected at an appropriate enforcement boundary even when a request bypasses normal conversational confirmation.
2.1 List events¶
The list_events tool retrieves events from the primary calendar and formats the response as a text list. Where available, the output includes the event summary and its start date or datetime.
| Parameter | Type | Default or behavior |
|---|---|---|
max_results |
Integer | Defaults to 10 in the chat plugin. |
time_min |
String | Optional ISO datetime start filter. |
time_max |
String | Optional ISO datetime end filter. |
The integration handler requests Google Calendar API v3 event data with the following behavior:
- Uses the primary calendar.
- Orders results by start time.
- Expands recurring events into individual occurrences.
- Defaults
max_resultsto10. - Defaults
time_minto the current UTC time when the parameter is absent.
The inspected route does not declare an upper bound for max_results.
Verification note
Confirm how pagination is handled, whether provider limits are respected, and whether excessively large max_results values are rejected or safely constrained.
2.2 Create an event¶
The create_event tool declares the following parameters.
| Parameter | Type | Required | Description |
|---|---|---|---|
summary |
String | Yes | Event title. |
start |
String | Yes | Event start datetime. |
end |
String | Yes | Event end datetime. |
description |
String | No | Event description. |
attendees |
Array of email addresses | No | Event attendees. |
The chat plugin checks that the event title, start, and end values are present. It constructs an event payload and sends it to the integrations service.
The handler forwards the JSON body to Google Calendar API v3 to create an event on the primary calendar. It accepts provider responses with status 200 or 201.
Implementation limitation: the inspected handler reads the request body as JSON rather than validating it against a dedicated event request model. Input validation, datetime semantics, attendee validation, and malformed-payload handling require separate verification.
This operation changes calendar state and is outside a strict read-only policy.
2.3 Delete an event¶
The delete_event tool accepts an event_id string.
The plugin sends a DELETE request to the integration route for that event. The handler issues a delete request against the primary Google Calendar and returns a response containing the deleted event identifier when the provider returns 200 or 204.
Deleting an event is a destructive, state-changing operation. It must not be available under a strict read-only integration policy.
3. Integration API endpoints¶
The inspected source declares the following service-level routes.
| Method | Endpoint | Purpose | Access classification |
|---|---|---|---|
GET |
/api/integrations-svc/google_cal/auth |
Starts Google Calendar OAuth. | Authentication flow |
GET |
/api/integrations-svc/google_cal/callback |
Handles the OAuth callback. | Authentication flow |
GET |
/api/integrations-svc/google_cal/events |
Lists calendar events. | Read |
POST |
/api/integrations-svc/google_cal/events |
Creates a calendar event. | Write |
DELETE |
/api/integrations-svc/google_cal/events/{event_id} |
Deletes a calendar event. | Write |
The access classifications above describe the intended purpose of each route, not a verified authorization result.
Route-level enforcement must be verified
Confirm that write routes are disabled or explicitly rejected when strict read-only mode is enabled. Review gateway exposure, internal authentication, user identity propagation, and any alternate invocation paths.
The externally reachable URLs depend on gateway proxy configuration and the deployment environment.
4. OAuth and credential management¶
4.1 Configuration variables¶
The inspected implementation references the following settings.
| Variable | Purpose |
|---|---|
GMAIL_CLIENT_ID |
Google OAuth client identifier used by this integration. |
GMAIL_CLIENT_SECRET |
Google OAuth client secret. |
GOOGLE_CAL_REDIRECT_URI |
Google Calendar OAuth callback URL. |
JWT_SECRET_KEY |
Used to validate the application token supplied when OAuth starts. |
JWT_ALGORITHM |
JWT validation algorithm. |
INTERNAL_SECRET |
Authenticates internal integration requests. |
FRONTEND_URL |
Frontend destination for OAuth callback outcomes. |
The chat plugin's env_vars property lists GMAIL_CLIENT_ID and GMAIL_CLIENT_SECRET. The integration handler additionally references GOOGLE_CAL_REDIRECT_URI and other application settings.
These references are not a complete deployment configuration specification. The actual values must be supplied through the deployment's approved secret-management mechanism.
Never expose credential values
Do not commit OAuth client secrets, JWT signing secrets, internal service secrets, access tokens, or refresh tokens to source control or documentation. Use redacted values in diagnostic output and examples.
4.2 Authorization flow¶
The inspected implementation follows this logical sequence.
sequenceDiagram
actor U as User
participant F as WhiteLotusAI Frontend
participant I as Integrations Service
participant G as Google OAuth
participant S as User Service
U->>F: Connect Google Calendar
F->>I: OAuth start with application token
I->>I: Decode token and obtain user ID
I->>I: Generate PKCE verifier, challenge, and state
I->>G: Redirect to authorization endpoint
G-->>U: Request consent
U->>G: Approve authorization
G->>I: Callback with code and state
I->>I: Validate and consume stored state
I->>G: Exchange code using PKCE verifier
G-->>I: Provider tokens
I->>S: Attempt token storage
I->>S: Attempt connection-status update
I-->>F: Redirect with outcome
The diagram summarizes the inspected flow; it does not establish that every failure path is handled securely or that all service calls succeed.
The implementation performs the following steps:
- Receives an application token in the OAuth start route's
tokenquery parameter. - Decodes the token and obtains the user identifier from the
subclaim. - Generates a PKCE verifier and challenge.
- Generates a random OAuth state value and stores the state, verifier, and user identifier.
- Redirects to Google's authorization endpoint with the configured client ID, callback URI, scopes, state, and PKCE challenge.
- Retrieves and removes the stored state entry during the callback.
- Exchanges the authorization code using the stored PKCE verifier.
- Requires a refresh token and attempts to store provider tokens through the user service.
- Attempts to mark the user's Google Calendar connection as active.
- Redirects the browser to the frontend with a success or error indicator.
The source checks for OAuth errors and rejects missing or invalid stored state. Further verification is needed for token validation, state-store behavior, callback failure handling, and safe handling of authentication errors.
4.3 Token resolution and refresh¶
The integration handler's token-resolution helper requires a user identifier and a matching INTERNAL_SECRET before resolving the user's stored Google Calendar token. It also checks whether the user has explicitly connected the integration.
The access-token helper:
- Checks whether the access token is missing or expired.
- Attempts to obtain a replacement access token when refresh is needed and a refresh token is available.
- Attempts to persist updated expiry information.
- Raises HTTP
401when an access token remains unavailable, indicating that Google Calendar is not connected.
The following cases remain unverified:
- Refresh-token rejection or revocation by Google.
- Failure to persist refreshed tokens or expiry information.
- Unavailable user-service or token-storage dependencies.
- Inconsistent connection-status and token records.
- Concurrent refresh requests for the same user.
5. OAuth scopes and permissions¶
The inspected handler requests these Google OAuth scopes:
| Scope | Purpose | Read-only compatibility |
|---|---|---|
openid |
OpenID Connect identity. | Compatible with read-only calendar access. |
https://www.googleapis.com/auth/userinfo.email |
Access to the user's email identity information. | Compatible with read-only calendar access. |
https://www.googleapis.com/auth/calendar.readonly |
Read calendar data. | Read-only. |
https://www.googleapis.com/auth/calendar.events |
Manage calendar events. | Broader than read-only. |
GCAL-02 — Scope exceeds the read-only requirement
The requested calendar.events scope grants event-management capabilities beyond a strictly read-only design.
The minimum required scope set must be reviewed before a read-only release. This documentation change does not modify application code or OAuth configuration.
OAuth scopes constrain provider-authorized capabilities; they do not replace application-level authorization checks. A read-only policy should be enforced independently in the tool registry and integration service.
6. Error handling and timeouts¶
The inspected code uses the following HTTP timeouts.
| Component | Timeout | Purpose |
|---|---|---|
| Chat plugin | 15 seconds | Requests to the integrations service. |
| Integration handlers | 10 seconds | Direct Google Calendar API requests. |
The chat plugin handles several response conditions:
- HTTP
401returns a message indicating that Google Calendar is not connected. - Other unsuccessful event-list responses produce a status-based error message.
- Failed create or delete requests produce operation-specific messages.
- Exceptions are logged as warnings, and the plugin returns a generic temporary-unavailability message.
The integration handlers raise HTTP exceptions when Google Calendar returns unsuccessful responses. Some error paths include provider response text in the exception detail.
Review provider errors and logs
Provider response bodies can contain diagnostic information that should not automatically be exposed to users or written to logs.
Verify error redaction, log access controls, exception propagation, and whether sensitive provider data can appear in upstream responses.
The presence of timeouts does not establish complete request cancellation, retry behavior, or consistent error handling across every failure path.
7. Date and time handling¶
The chat plugin's default time-range helper uses UTC.
| Request interpretation | Inspected behavior |
|---|---|
today |
Creates a UTC day range. |
tomorrow |
Creates the next UTC day range. |
this week |
Uses the current time through the next seven days. |
next week |
Uses a seven-day range beginning seven days from the current time. |
| Other requests | Defaults to the next seven days. |
The helper does not derive the user's local timezone from the request.
The create-event helper also appends Z to datetime strings that do not already include a timezone offset or Z, treating those values as UTC.
This behavior may produce unexpected event selection or scheduling when a user expresses times in a local timezone.
Timezone verification
Verify that natural-language dates are interpreted in the intended timezone, that ambiguous datetime inputs are handled explicitly, and that event start and end values are sent to Google in the expected format.
Do not assume the user's local timezone is applied merely because the request originates from the frontend.
8. Caching and health reporting¶
Caching¶
The integrations handler module describes Redis-backed caching for integration results. The precise cache coverage and invalidation behavior for Google Calendar must be verified against the relevant handler and cache calls.
Review at least the following:
- Whether calendar event responses are cached.
- Whether cache keys isolate individual users and relevant query parameters.
- Whether event changes invalidate cached results.
- Whether cached data can remain accessible after a user disconnects the integration.
- Whether token or credential data is excluded from inappropriate cache entries.
These are verification questions, not confirmed cache defects.
Health reporting¶
The chat plugin's health_check method returns True and describes the integration as OAuth-only, with connection validity checked during execution.
A successful plugin health check does not establish that:
- A particular user's OAuth connection is valid.
- The stored refresh token remains usable.
- Google Calendar is reachable.
- The user has sufficient provider permissions.
- A calendar operation will succeed.
Distinguish plugin registration health from per-user connection health and provider availability in operational monitoring.
9. Security and verification findings¶
The following register records source-review findings and follow-up requirements. No application code has been modified as part of this documentation update.
| ID | Finding | Required follow-up |
|---|---|---|
| GCAL-01 | Event creation and deletion are declared as write tools with corresponding service routes. | Verify read-only enforcement across tool dispatch, service routes, and alternate entry points. |
| GCAL-02 | OAuth requests calendar.events in addition to calendar.readonly. |
Review the minimum scope set for the intended read-only release. |
| GCAL-03 | The event-list route does not declare an upper bound for max_results. |
Verify pagination, provider limits, and input constraints. |
| GCAL-04 | The create-event handler forwards JSON without a dedicated event request model in the inspected code. | Verify input validation and rejection of malformed event data. |
| GCAL-05 | The token-exchange failure path logs provider response text. | Review sensitive-data exposure and log redaction. |
| GCAL-06 | Default date-range parsing uses UTC without resolving the user's local timezone. | Verify timezone semantics and expected user experience. |
| GCAL-07 | Access-token refresh and token-persistence failure paths require verification. | Test expiry, refresh failure, revocation, and storage outages. |
| GCAL-08 | The plugin health check always returns True. |
Distinguish plugin registration from connection and provider health. |
| GCAL-09 | Plugin environment metadata does not list every setting referenced by the OAuth handler. | Reconcile plugin metadata with deployment configuration documentation. |
| GCAL-10 | End-to-end behavior has not been established for all calendar operations. | Verify route exposure, identity propagation, provider responses, and integration tests. |
Finding classification
These items represent source-review observations and verification gaps. They do not establish that a vulnerability has been exploited or that a runtime failure has been reproduced.
Recommended verification order¶
- Security boundary: establish that write operations are rejected throughout the application when read-only mode is required.
- OAuth permissions: confirm the minimum scopes and validate user consent and token handling.
- Identity isolation: verify that every request resolves credentials for the authenticated user and cannot access another user's calendar.
- Input and resource limits: validate event-list parameters, request payloads, pagination, and datetime inputs.
- Reliability: test token refresh, provider errors, storage outages, timeouts, and recovery behavior.
- Observability: verify health reporting, cache invalidation, and safe logging.
- End-to-end coverage: execute integration tests against a dedicated test calendar and document the actual results.
10. Source references¶
The following files are the primary source locations identified during this review.
| Source file | Review focus |
|---|---|
chat/package/app/plugins/google_cal/plugin.py |
Tool definitions, HTTP requests, date-range defaults, formatting, and health reporting. |
integrations/package/app/handlers/integration_handlers.py |
OAuth flow, credential resolution, token refresh, routes, and provider error handling. |
integrations/package/app/managers/google_cal_client.py |
Google Calendar API client operations. |
integrations/package/app/managers/cache.py |
Shared caching implementation and invalidation behavior. |
integrations/package/app/settings.py |
Integration and application configuration references. |
11. Verification status and maintenance¶
| Area | Documentation status |
|---|---|
| Tool definitions and declared routes | Source-inspected |
| OAuth flow and requested scopes | Source-inspected; security verification pending |
| Token refresh and persistence | Runtime verification pending |
| Read-only enforcement | Not established |
| Timezone behavior | Runtime verification pending |
| Cache behavior | Targeted source review and verification pending |
| End-to-end operation | Not established |
Update this page when new source inspection, automated tests, or runtime evidence changes a finding. Record the test environment, test result, and relevant implementation revision when marking a verification item complete.
Acceptance criterion for a read-only release: event retrieval must work for the authorized user, while event creation and deletion must be rejected at the applicable enforcement boundaries. OAuth permissions must also be consistent with the approved read-only design.
Related documentation: Third-Party Integrations · Read-Only Integration Test Plan · Security Overview